@@ -0,0 +1,257 @@
+
+# Created by https://www.toptal.com/developers/gitignore/api/python,serverless,node
+# Edit at https://www.toptal.com/developers/gitignore?templates=python,serverless,node
+### Node ###
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+lerna-debug.log*
+# Diagnostic reports (https://nodejs.org/api/report.html)
+report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
+# Runtime data
+pids
+*.pid
+*.seed
+*.pid.lock
+# Directory for instrumented libs generated by jscoverage/JSCover
+lib-cov
+# Coverage directory used by tools like istanbul
+coverage
+*.lcov
+# nyc test coverage
+.nyc_output
+# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
+.grunt
+# Bower dependency directory (https://bower.io/)
+bower_components
+# node-waf configuration
+.lock-wscript
+# Compiled binary addons (https://nodejs.org/api/addons.html)
+build/Release
+# Dependency directories
+node_modules/
+jspm_packages/
+# TypeScript v1 declaration files
+typings/
+# TypeScript cache
+*.tsbuildinfo
+# Optional npm cache directory
+.npm
+# Optional eslint cache
+.eslintcache
+# Microbundle cache
+.rpt2_cache/
+.rts2_cache_cjs/
+.rts2_cache_es/
+.rts2_cache_umd/
+# Optional REPL history
+.node_repl_history
+# Output of 'npm pack'
+*.tgz
+# Yarn Integrity file
+.yarn-integrity
+# dotenv environment variables file
+.env
+.env.test
+.env*.local
+# parcel-bundler cache (https://parceljs.org/)
+.cache
+.parcel-cache
+# Next.js build output
+.next
+# Nuxt.js build / generate output
+.nuxt
+dist
+# Gatsby files
+.cache/
+# Comment in the public line in if your project uses Gatsby and not Next.js
+# https://nextjs.org/blog/next-9-1#public-directory-support
+# public
+# vuepress build output
+.vuepress/dist
+# Serverless directories
+.serverless/
+# FuseBox cache
+.fusebox/
+# DynamoDB Local files
+.dynamodb/
+# TernJS port file
+.tern-port
+# Stores VSCode versions used for testing VSCode extensions
+.vscode-test
+### Python ###
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+# C extensions
+*.so
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+pip-wheel-metadata/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+# PyInstaller
+# Usually these files are written by a python script from a template
+# before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+nosetests.xml
+coverage.xml
+*.cover
+*.py,cover
+.hypothesis/
+.pytest_cache/
+pytestdebug.log
+# Translations
+*.mo
+*.pot
+# Django stuff:
+local_settings.py
+db.sqlite3
+db.sqlite3-journal
+# Flask stuff:
+instance/
+.webassets-cache
+# Scrapy stuff:
+.scrapy
+# Sphinx documentation
+docs/_build/
+doc/_build/
+# PyBuilder
+target/
+# Jupyter Notebook
+.ipynb_checkpoints
+# IPython
+profile_default/
+ipython_config.py
+# pyenv
+.python-version
+# pipenv
+# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
+# However, in case of collaboration, if having platform-specific dependencies or dependencies
+# having no cross-platform support, pipenv may install dependencies that don't work, or not
+# install all needed dependencies.
+#Pipfile.lock
+# PEP 582; used by e.g. github.com/David-OConnor/pyflow
+__pypackages__/
+# Celery stuff
+celerybeat-schedule
+celerybeat.pid
+# SageMath parsed files
+*.sage.py
+# Environments
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+pythonenv*
+# Spyder project settings
+.spyderproject
+.spyproject
+# Rope project settings
+.ropeproject
+# mkdocs documentation
+/site
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+# Pyre type checker
+.pyre/
+# pytype static type analyzer
+.pytype/
+# profiling data
+.prof
+### Serverless ###
+# Ignore build directory
+.serverless
+# End of https://www.toptal.com/developers/gitignore/api/python,serverless,node
@@ -0,0 +1,20 @@
@@ -0,0 +1,82 @@
+{
+ "AWSTemplateFormatVersion": "2010-09-09",
+ "Description": "The AWS CloudFormation template for this Serverless application",
+ "Resources": {
+ "ServerlessDeploymentBucket": {
+ "Type": "AWS::S3::Bucket",
+ "Properties": {
+ "BucketEncryption": {
+ "ServerSideEncryptionConfiguration": [
+ {
+ "ServerSideEncryptionByDefault": {
+ "SSEAlgorithm": "AES256"
+ }
+ ]
+ },
+ "ServerlessDeploymentBucketPolicy": {
+ "Type": "AWS::S3::BucketPolicy",
+ "Bucket": {
+ "Ref": "ServerlessDeploymentBucket"
+ "PolicyDocument": {
+ "Statement": [
+ "Action": "s3:*",
+ "Effect": "Deny",
+ "Principal": "*",
+ "Resource": [
+ "Fn::Join": [
+ "",
+ [
+ "arn:",
+ "Ref": "AWS::Partition"
+ ":s3:::",
+ "/*"
+ ],
+ "Condition": {
+ "Bool": {
+ "aws:SecureTransport": false
+ "Outputs": {
+ "ServerlessDeploymentBucketName": {
+ "Value": {
+}
@@ -0,0 +1,256 @@
+ "NumpyLogGroup": {
+ "Type": "AWS::Logs::LogGroup",
+ "LogGroupName": "/aws/lambda/ambt-anoicos-dev-numpy"
+ "IamRoleLambdaExecution": {
+ "Type": "AWS::IAM::Role",
+ "AssumeRolePolicyDocument": {
+ "Version": "2012-10-17",
+ "Effect": "Allow",
+ "Principal": {
+ "Service": [
+ "lambda.amazonaws.com"
+ "Action": [
+ "sts:AssumeRole"
+ "Policies": [
+ "PolicyName": {
+ "-",
+ "ambt-anoicos",
+ "dev",
+ "lambda"
+ "logs:CreateLogStream",
+ "logs:CreateLogGroup"
+ "Fn::Sub": "arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/ambt-anoicos-dev*:*"
+ "logs:PutLogEvents"
+ "Fn::Sub": "arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/ambt-anoicos-dev*:*:*"
+ "Path": "/",
+ "RoleName": {
+ "Ref": "AWS::Region"
+ "lambdaRole"
+ "PythonRequirementsLambdaLayer": {
+ "Type": "AWS::Lambda::LayerVersion",
+ "Content": {
+ "S3Bucket": {
+ "S3Key": "serverless/ambt-anoicos/dev/1623974011018-2021-06-17T23:53:31.018Z/pythonRequirements.zip"
+ "LayerName": "ambt-anoicos-dev-python-requirements",
+ "Description": "Python requirements generated by serverless-python-requirements.",
+ "CompatibleRuntimes": [
+ "python3.8"
+ "NumpyLambdaFunction": {
+ "Type": "AWS::Lambda::Function",
+ "Code": {
+ "S3Key": "serverless/ambt-anoicos/dev/1623974011018-2021-06-17T23:53:31.018Z/ambt-anoicos.zip"
+ "Handler": "handler.main",
+ "Runtime": "python3.8",
+ "FunctionName": "ambt-anoicos-dev-numpy",
+ "MemorySize": 1024,
+ "Timeout": 6,
+ "Role": {
+ "Fn::GetAtt": [
+ "IamRoleLambdaExecution",
+ "Arn"
+ "Layers": [
+ "Ref": "PythonRequirementsLambdaLayer"
+ "DependsOn": [
+ "NumpyLogGroup"
+ "NumpyLambdaVersion4nqiRdtNg2AbGSGlzGV12aNY2OuUh7esxvqofgY": {
+ "Type": "AWS::Lambda::Version",
+ "DeletionPolicy": "Retain",
+ "FunctionName": {
+ "Ref": "NumpyLambdaFunction"
+ "CodeSha256": "IVZ5bTPa382jcJBMQHlQd0Zn9gjSEEfl2vSmrUqAhWk="
+ "Export": {
+ "Name": "sls-ambt-anoicos-dev-ServerlessDeploymentBucketName"
+ "PythonRequirementsLambdaLayerQualifiedArn": {
+ "Description": "Current Lambda layer version",
+ "Name": "sls-ambt-anoicos-dev-PythonRequirementsLambdaLayerQualifiedArn"
+ "PythonRequirementsLambdaLayerHash": {
+ "Description": "Current Lambda layer hash",
+ "Value": "35b9f3a28aa474ce779bef4f48b8e95d200c045e",
+ "Name": "sls-ambt-anoicos-dev-PythonRequirementsLambdaLayerHash"
+ "PythonRequirementsLambdaLayerS3Key": {
+ "Description": "Current Lambda layer S3Key",
+ "Value": "serverless/ambt-anoicos/dev/1623974011018-2021-06-17T23:53:31.018Z/pythonRequirements.zip",
+ "Name": "sls-ambt-anoicos-dev-PythonRequirementsLambdaLayerS3Key"
+ "NumpyLambdaFunctionQualifiedArn": {
+ "Description": "Current Lambda function version",
+ "Ref": "NumpyLambdaVersion4nqiRdtNg2AbGSGlzGV12aNY2OuUh7esxvqofgY"
+ "Name": "sls-ambt-anoicos-dev-NumpyLambdaFunctionQualifiedArn"
@@ -0,0 +1 @@
+numpy==1.20.3
@@ -0,0 +1,938 @@
+----
+This binary distribution of NumPy also bundles the following software:
+Name: OpenBLAS
+Files: extra-dll\libopenb*.dll
+Description: bundled as a dynamically linked library
+Availability: https://github.com/xianyi/OpenBLAS/
+License: 3-clause BSD
+ Copyright (c) 2011-2014, The OpenBLAS 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:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the OpenBLAS project nor the names of
+ its contributors may be used to endorse or promote products
+ derived from this software without specific prior written
+ permission.
+ 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.
+Name: LAPACK
+Description: bundled in OpenBLAS
+License 3-clause BSD
+ Copyright (c) 1992-2013 The University of Tennessee and The University
+ of Tennessee Research Foundation. All rights
+ reserved.
+ Copyright (c) 2000-2013 The University of California Berkeley. All
+ rights reserved.
+ Copyright (c) 2006-2013 The University of Colorado Denver. All rights
+ $COPYRIGHT$
+ Additional copyrights may follow
+ $HEADER$
+ - Redistributions of source code must retain the above copyright
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer listed
+ in this license in the documentation and/or other materials
+ provided with the distribution.
+ - Neither the name of the copyright holders nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+ The copyright holders provide no reassurances that the source code
+ provided does not infringe any patent, copyright, or any other
+ intellectual property rights of third parties. The copyright holders
+ disclaim any liability to any recipient for claims brought against
+ recipient by any third party for infringement of that parties
+ intellectual property rights.
+ 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.
+Name: GCC runtime library
+Files: extra-dll\*.dll
+Description: statically linked, in DLL files compiled with gfortran only
+Availability: https://gcc.gnu.org/viewcvs/gcc/
+License: GPLv3 + runtime exception
+ Copyright (C) 2002-2017 Free Software Foundation, Inc.
+ Libgfortran is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+ Libgfortran is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>.
+Name: Microsoft Visual C++ Runtime Files
+Files: extra-dll\msvcp140.dll
+License: MSVC
+ https://www.visualstudio.com/license-terms/distributable-code-microsoft-visual-studio-2015-rc-microsoft-visual-studio-2015-sdk-rc-includes-utilities-buildserver-files/#visual-c-runtime
+ Subject to the License Terms for the software, you may copy and
+ distribute with your program any of the files within the followng
+ folder and its subfolders except as noted below. You may not modify
+ these files.
+ C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\redist
+ You may not distribute the contents of the following folders:
+ C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\redist\debug_nonredist
+ C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\redist\onecore\debug_nonredist
+ distribute the following files with your program in your program’s
+ application local folder or by deploying them into the Global
+ Assembly Cache (GAC):
+ VC\atlmfc\lib\mfcmifc80.dll
+ VC\atlmfc\lib\amd64\mfcmifc80.dll
+Files: extra-dll\msvc*90.dll, extra-dll\Microsoft.VC90.CRT.manifest
+ For your convenience, we have provided the following folders for
+ use when redistributing VC++ runtime files. Subject to the license
+ terms for the software, you may redistribute the folder
+ (unmodified) in the application local folder as a sub-folder with
+ no change to the folder name. You may also redistribute all the
+ files (*.dll and *.manifest) within a folder, listed below the
+ folder for your convenience, as an entire set.
+ \VC\redist\x86\Microsoft.VC90.ATL\
+ atl90.dll
+ Microsoft.VC90.ATL.manifest
+ \VC\redist\ia64\Microsoft.VC90.ATL\
+ \VC\redist\amd64\Microsoft.VC90.ATL\
+ \VC\redist\x86\Microsoft.VC90.CRT\
+ msvcm90.dll
+ msvcp90.dll
+ msvcr90.dll
+ Microsoft.VC90.CRT.manifest
+ \VC\redist\ia64\Microsoft.VC90.CRT\
+Full text of license texts referred to above follows (that they are
+listed below does not necessarily imply the conditions apply to the
+present binary release):
+GCC RUNTIME LIBRARY EXCEPTION
+Version 3.1, 31 March 2009
+Copyright (C) 2009 Free Software Foundation, Inc. <http://fsf.org/>
+Everyone is permitted to copy and distribute verbatim copies of this
+license document, but changing it is not allowed.
+This GCC Runtime Library Exception ("Exception") is an additional
+permission under section 7 of the GNU General Public License, version
+3 ("GPLv3"). It applies to a given file (the "Runtime Library") that
+bears a notice placed by the copyright holder of the file stating that
+the file is governed by GPLv3 along with this Exception.
+When you use GCC to compile a program, GCC may combine portions of
+certain GCC header files and runtime libraries with the compiled
+program. The purpose of this Exception is to allow compilation of
+non-GPL (including proprietary) programs to use, in this way, the
+header files and runtime libraries covered by this Exception.
+0. Definitions.
+A file is an "Independent Module" if it either requires the Runtime
+Library for execution after a Compilation Process, or makes use of an
+interface provided by the Runtime Library, but is not otherwise based
+on the Runtime Library.
+"GCC" means a version of the GNU Compiler Collection, with or without
+modifications, governed by version 3 (or a specified later version) of
+the GNU General Public License (GPL) with the option of using any
+subsequent versions published by the FSF.
+"GPL-compatible Software" is software whose conditions of propagation,
+modification and use would permit combination with GCC in accord with
+the license of GCC.
+"Target Code" refers to output from any compiler for a real or virtual
+target processor architecture, in executable form or suitable for
+input to an assembler, loader, linker and/or execution
+phase. Notwithstanding that, Target Code does not include data in any
+format that is used as a compiler intermediate representation, or used
+for producing a compiler intermediate representation.
+The "Compilation Process" transforms code entirely represented in
+non-intermediate languages designed for human-written code, and/or in
+Java Virtual Machine byte code, into Target Code. Thus, for example,
+use of source code generators and preprocessors need not be considered
+part of the Compilation Process, since the Compilation Process can be
+understood as starting with the output of the generators or
+preprocessors.
+A Compilation Process is "Eligible" if it is done using GCC, alone or
+with other GPL-compatible software, or if it is done without using any
+work based on GCC. For example, using non-GPL-compatible Software to
+optimize any GCC intermediate representations would not qualify as an
+Eligible Compilation Process.
+1. Grant of Additional Permission.
+You have permission to propagate a work of Target Code formed by
+combining the Runtime Library with Independent Modules, even if such
+propagation would otherwise violate the terms of GPLv3, provided that
+all Target Code was generated by Eligible Compilation Processes. You
+may then convey such a combination under terms of your choice,
+consistent with the licensing of the Independent Modules.
+2. No Weakening of GCC Copyleft.
+The availability of this Exception does not imply any general
+presumption that third-party software is unaffected by the copyleft
+requirements of the license of GCC.
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+ Preamble
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+ The precise terms and conditions for copying, distribution and
+modification follow.
+ TERMS AND CONDITIONS
+ 0. Definitions.
+ "This License" refers to version 3 of the GNU General Public License.
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+ 1. Source Code.
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+ The Corresponding Source for a work in source code form is that
+same work.
+ 2. Basic Permissions.
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+ 4. Conveying Verbatim Copies.
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+ 5. Conveying Modified Source Versions.
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+ 6. Conveying Non-Source Forms.
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+ 7. Additional Terms.
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+ 8. Termination.
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+ 9. Acceptance Not Required for Having Copies.
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+ 10. Automatic Licensing of Downstream Recipients.
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+ 11. Patents.
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+ 12. No Surrender of Others' Freedom.
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+ 13. Use with the GNU Affero General Public License.
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+ 14. Revised Versions of this License.
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+ 15. Disclaimer of Warranty.
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+ 16. Limitation of Liability.
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+ 17. Interpretation of Sections 15 and 16.
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+ END OF TERMS AND CONDITIONS
+ How to Apply These Terms to Your New Programs
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+ This program is free software: you can redistribute it and/or modify
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+ This program is distributed in the hope that it will be useful,
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+Also add information on how to contact you by electronic and paper mail.
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
@@ -0,0 +1,78 @@
+# This file is generated by numpy's setup.py
+# It contains system_info results at the time of building this package.
+__all__ = ["get_info","show"]
+import os
+import sys
+extra_dll_dir = os.path.join(os.path.dirname(__file__), '.libs')
+if sys.platform == 'win32' and os.path.isdir(extra_dll_dir):
+ if sys.version_info >= (3, 8):
+ os.add_dll_directory(extra_dll_dir)
+ else:
+ os.environ.setdefault('PATH', '')
+ os.environ['PATH'] += os.pathsep + extra_dll_dir
+blas_mkl_info={}
+blis_info={}
+openblas_info={'library_dirs': ['D:\\a\\1\\s\\numpy\\build\\openblas_info'], 'libraries': ['openblas_info'], 'language': 'f77', 'define_macros': [('HAVE_CBLAS', None)]}
+blas_opt_info={'library_dirs': ['D:\\a\\1\\s\\numpy\\build\\openblas_info'], 'libraries': ['openblas_info'], 'language': 'f77', 'define_macros': [('HAVE_CBLAS', None)]}
+lapack_mkl_info={}
+openblas_lapack_info={'library_dirs': ['D:\\a\\1\\s\\numpy\\build\\openblas_lapack_info'], 'libraries': ['openblas_lapack_info'], 'language': 'f77', 'define_macros': [('HAVE_CBLAS', None)]}
+lapack_opt_info={'library_dirs': ['D:\\a\\1\\s\\numpy\\build\\openblas_lapack_info'], 'libraries': ['openblas_lapack_info'], 'language': 'f77', 'define_macros': [('HAVE_CBLAS', None)]}
+def get_info(name):
+ g = globals()
+ return g.get(name, g.get(name + "_info", {}))
+def show():
+ """
+ Show libraries in the system on which NumPy was built.
+ Print information about various resources (libraries, library
+ directories, include directories, etc.) in the system on which
+ NumPy was built.
+ See Also
+ --------
+ get_include : Returns the directory containing NumPy C
+ header files.
+ 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``
+ Examples
+ >>> import numpy as np
+ >>> np.show_config()
+ blas_opt_info:
+ language = c
+ define_macros = [('HAVE_CBLAS', None)]
+ libraries = ['openblas', 'openblas']
+ library_dirs = ['/usr/local/lib']
+ for name,info_dict in globals().items():
+ if name[0] == "_" or type(info_dict) is not type({}): continue
+ print(name + ":")
+ if not info_dict:
+ print(" NOT AVAILABLE")
+ for k,v in info_dict.items():
+ v = str(v)
+ if k == "sources" and len(v) > 200:
+ v = v[:60] + " ...\n... " + v[-60:]
+ print(" %s = %s" % (k,v))
@@ -0,0 +1,1055 @@
+# NumPy static imports for Cython >= 3.0
+#
+# If any of the PyArray_* functions are called, import_array must be
+# called first. This is done automatically by Cython 3.0+ if a call
+# is not detected inside of the module.
+# Author: Dag Sverre Seljebotn
+from cpython.ref cimport Py_INCREF
+from cpython.object cimport PyObject, PyTypeObject, PyObject_TypeCheck
+cimport libc.stdio as stdio
+cdef extern from *:
+ # Leave a marker that the NumPy declarations came from NumPy itself and not from Cython.
+ # See https://github.com/cython/cython/issues/3573
+ /* Using NumPy API declarations from "numpy/__init__.cython-30.pxd" */
+cdef extern from "Python.h":
+ ctypedef Py_ssize_t Py_intptr_t
+cdef extern from "numpy/arrayobject.h":
+ ctypedef Py_intptr_t npy_intp
+ ctypedef size_t npy_uintp
+ cdef enum NPY_TYPES:
+ NPY_BOOL
+ NPY_BYTE
+ NPY_UBYTE
+ NPY_SHORT
+ NPY_USHORT
+ NPY_INT
+ NPY_UINT
+ NPY_LONG
+ NPY_ULONG
+ NPY_LONGLONG
+ NPY_ULONGLONG
+ NPY_FLOAT
+ NPY_DOUBLE
+ NPY_LONGDOUBLE
+ NPY_CFLOAT
+ NPY_CDOUBLE
+ NPY_CLONGDOUBLE
+ NPY_OBJECT
+ NPY_STRING
+ NPY_UNICODE
+ NPY_VOID
+ NPY_DATETIME
+ NPY_TIMEDELTA
+ NPY_NTYPES
+ NPY_NOTYPE
+ NPY_INT8
+ NPY_INT16
+ NPY_INT32
+ NPY_INT64
+ NPY_INT128
+ NPY_INT256
+ NPY_UINT8
+ NPY_UINT16
+ NPY_UINT32
+ NPY_UINT64
+ NPY_UINT128
+ NPY_UINT256
+ NPY_FLOAT16
+ NPY_FLOAT32
+ NPY_FLOAT64
+ NPY_FLOAT80
+ NPY_FLOAT96
+ NPY_FLOAT128
+ NPY_FLOAT256
+ NPY_COMPLEX32
+ NPY_COMPLEX64
+ NPY_COMPLEX128
+ NPY_COMPLEX160
+ NPY_COMPLEX192
+ NPY_COMPLEX256
+ NPY_COMPLEX512
+ NPY_INTP
+ ctypedef enum NPY_ORDER:
+ NPY_ANYORDER
+ NPY_CORDER
+ NPY_FORTRANORDER
+ NPY_KEEPORDER
+ ctypedef enum NPY_CASTING:
+ NPY_NO_CASTING
+ NPY_EQUIV_CASTING
+ NPY_SAFE_CASTING
+ NPY_SAME_KIND_CASTING
+ NPY_UNSAFE_CASTING
+ ctypedef enum NPY_CLIPMODE:
+ NPY_CLIP
+ NPY_WRAP
+ NPY_RAISE
+ ctypedef enum NPY_SCALARKIND:
+ NPY_NOSCALAR,
+ NPY_BOOL_SCALAR,
+ NPY_INTPOS_SCALAR,
+ NPY_INTNEG_SCALAR,
+ NPY_FLOAT_SCALAR,
+ NPY_COMPLEX_SCALAR,
+ NPY_OBJECT_SCALAR
+ ctypedef enum NPY_SORTKIND:
+ NPY_QUICKSORT
+ NPY_HEAPSORT
+ NPY_MERGESORT
+ ctypedef enum NPY_SEARCHSIDE:
+ NPY_SEARCHLEFT
+ NPY_SEARCHRIGHT
+ enum:
+ # DEPRECATED since NumPy 1.7 ! Do not use in new code!
+ NPY_C_CONTIGUOUS
+ NPY_F_CONTIGUOUS
+ NPY_CONTIGUOUS
+ NPY_FORTRAN
+ NPY_OWNDATA
+ NPY_FORCECAST
+ NPY_ENSURECOPY
+ NPY_ENSUREARRAY
+ NPY_ELEMENTSTRIDES
+ NPY_ALIGNED
+ NPY_NOTSWAPPED
+ NPY_WRITEABLE
+ NPY_UPDATEIFCOPY
+ NPY_ARR_HAS_DESCR
+ NPY_BEHAVED
+ NPY_BEHAVED_NS
+ NPY_CARRAY
+ NPY_CARRAY_RO
+ NPY_FARRAY
+ NPY_FARRAY_RO
+ NPY_DEFAULT
+ NPY_IN_ARRAY
+ NPY_OUT_ARRAY
+ NPY_INOUT_ARRAY
+ NPY_IN_FARRAY
+ NPY_OUT_FARRAY
+ NPY_INOUT_FARRAY
+ NPY_UPDATE_ALL
+ # Added in NumPy 1.7 to replace the deprecated enums above.
+ NPY_ARRAY_C_CONTIGUOUS
+ NPY_ARRAY_F_CONTIGUOUS
+ NPY_ARRAY_OWNDATA
+ NPY_ARRAY_FORCECAST
+ NPY_ARRAY_ENSURECOPY
+ NPY_ARRAY_ENSUREARRAY
+ NPY_ARRAY_ELEMENTSTRIDES
+ NPY_ARRAY_ALIGNED
+ NPY_ARRAY_NOTSWAPPED
+ NPY_ARRAY_WRITEABLE
+ NPY_ARRAY_UPDATEIFCOPY
+ NPY_ARRAY_BEHAVED
+ NPY_ARRAY_BEHAVED_NS
+ NPY_ARRAY_CARRAY
+ NPY_ARRAY_CARRAY_RO
+ NPY_ARRAY_FARRAY
+ NPY_ARRAY_FARRAY_RO
+ NPY_ARRAY_DEFAULT
+ NPY_ARRAY_IN_ARRAY
+ NPY_ARRAY_OUT_ARRAY
+ NPY_ARRAY_INOUT_ARRAY
+ NPY_ARRAY_IN_FARRAY
+ NPY_ARRAY_OUT_FARRAY
+ NPY_ARRAY_INOUT_FARRAY
+ NPY_ARRAY_UPDATE_ALL
+ cdef enum:
+ NPY_MAXDIMS
+ npy_intp NPY_MAX_ELSIZE
+ ctypedef void (*PyArray_VectorUnaryFunc)(void *, void *, npy_intp, void *, void *)
+ ctypedef struct PyArray_ArrayDescr:
+ # shape is a tuple, but Cython doesn't support "tuple shape"
+ # inside a non-PyObject declaration, so we have to declare it
+ # as just a PyObject*.
+ PyObject* shape
+ ctypedef struct PyArray_Descr:
+ pass
+ ctypedef class numpy.dtype [object PyArray_Descr, check_size ignore]:
+ # Use PyDataType_* macros when possible, however there are no macros
+ # for accessing some of the fields, so some are defined.
+ cdef PyTypeObject* typeobj
+ cdef char kind
+ cdef char type
+ # Numpy sometimes mutates this without warning (e.g. it'll
+ # sometimes change "|" to "<" in shared dtype objects on
+ # little-endian machines). If this matters to you, use
+ # PyArray_IsNativeByteOrder(dtype.byteorder) instead of
+ # directly accessing this field.
+ cdef char byteorder
+ cdef char flags
+ cdef int type_num
+ cdef int itemsize "elsize"
+ cdef int alignment
+ cdef object fields
+ cdef tuple names
+ # Use PyDataType_HASSUBARRAY to test whether this field is
+ # valid (the pointer can be NULL). Most users should access
+ # this field via the inline helper method PyDataType_SHAPE.
+ cdef PyArray_ArrayDescr* subarray
+ ctypedef class numpy.flatiter [object PyArrayIterObject, check_size ignore]:
+ # Use through macros
+ ctypedef class numpy.broadcast [object PyArrayMultiIterObject, check_size ignore]:
+ ctypedef struct PyArrayObject:
+ # For use in situations where ndarray can't replace PyArrayObject*,
+ # like PyArrayObject**.
+ ctypedef class numpy.ndarray [object PyArrayObject, check_size ignore]:
+ cdef __cythonbufferdefaults__ = {"mode": "strided"}
+ # NOTE: no field declarations since direct access is deprecated since NumPy 1.7
+ # Instead, we use properties that map to the corresponding C-API functions.
+ @property
+ cdef inline PyObject* base(self) nogil:
+ """Returns a borrowed reference to the object owning the data/memory.
+ return PyArray_BASE(self)
+ cdef inline dtype descr(self):
+ """Returns an owned reference to the dtype of the array.
+ return <dtype>PyArray_DESCR(self)
+ cdef inline int ndim(self) nogil:
+ """Returns the number of dimensions in the array.
+ return PyArray_NDIM(self)
+ cdef inline npy_intp *shape(self) nogil:
+ """Returns a pointer to the dimensions/shape of the array.
+ The number of elements matches the number of dimensions of the array (ndim).
+ Can return NULL for 0-dimensional arrays.
+ return PyArray_DIMS(self)
+ cdef inline npy_intp *strides(self) nogil:
+ """Returns a pointer to the strides of the array.
+ return PyArray_STRIDES(self)
+ cdef inline npy_intp size(self) nogil:
+ """Returns the total size (in number of elements) of the array.
+ return PyArray_SIZE(self)
+ cdef inline char* data(self) nogil:
+ """The pointer to the data buffer as a char*.
+ This is provided for legacy reasons to avoid direct struct field access.
+ For new code that needs this access, you probably want to cast the result
+ of `PyArray_DATA()` instead, which returns a 'void*'.
+ return PyArray_BYTES(self)
+ ctypedef unsigned char npy_bool
+ ctypedef signed char npy_byte
+ ctypedef signed short npy_short
+ ctypedef signed int npy_int
+ ctypedef signed long npy_long
+ ctypedef signed long long npy_longlong
+ ctypedef unsigned char npy_ubyte
+ ctypedef unsigned short npy_ushort
+ ctypedef unsigned int npy_uint
+ ctypedef unsigned long npy_ulong
+ ctypedef unsigned long long npy_ulonglong
+ ctypedef float npy_float
+ ctypedef double npy_double
+ ctypedef long double npy_longdouble
+ ctypedef signed char npy_int8
+ ctypedef signed short npy_int16
+ ctypedef signed int npy_int32
+ ctypedef signed long long npy_int64
+ ctypedef signed long long npy_int96
+ ctypedef signed long long npy_int128
+ ctypedef unsigned char npy_uint8
+ ctypedef unsigned short npy_uint16
+ ctypedef unsigned int npy_uint32
+ ctypedef unsigned long long npy_uint64
+ ctypedef unsigned long long npy_uint96
+ ctypedef unsigned long long npy_uint128
+ ctypedef float npy_float32
+ ctypedef double npy_float64
+ ctypedef long double npy_float80
+ ctypedef long double npy_float96
+ ctypedef long double npy_float128
+ ctypedef struct npy_cfloat:
+ float real
+ float imag
+ ctypedef struct npy_cdouble:
+ double real
+ double imag
+ ctypedef struct npy_clongdouble:
+ long double real
+ long double imag
+ ctypedef struct npy_complex64:
+ ctypedef struct npy_complex128:
+ ctypedef struct npy_complex160:
+ ctypedef struct npy_complex192:
+ ctypedef struct npy_complex256:
+ ctypedef struct PyArray_Dims:
+ npy_intp *ptr
+ int len
+ int _import_array() except -1
+ # A second definition so _import_array isn't marked as used when we use it here.
+ # Do not use - subject to change any time.
+ int __pyx_import_array "_import_array"() except -1
+ #
+ # Macros from ndarrayobject.h
+ bint PyArray_CHKFLAGS(ndarray m, int flags) nogil
+ bint PyArray_IS_C_CONTIGUOUS(ndarray arr) nogil
+ bint PyArray_IS_F_CONTIGUOUS(ndarray arr) nogil
+ bint PyArray_ISCONTIGUOUS(ndarray m) nogil
+ bint PyArray_ISWRITEABLE(ndarray m) nogil
+ bint PyArray_ISALIGNED(ndarray m) nogil
+ int PyArray_NDIM(ndarray) nogil
+ bint PyArray_ISONESEGMENT(ndarray) nogil
+ bint PyArray_ISFORTRAN(ndarray) nogil
+ int PyArray_FORTRANIF(ndarray) nogil
+ void* PyArray_DATA(ndarray) nogil
+ char* PyArray_BYTES(ndarray) nogil
+ npy_intp* PyArray_DIMS(ndarray) nogil
+ npy_intp* PyArray_STRIDES(ndarray) nogil
+ npy_intp PyArray_DIM(ndarray, size_t) nogil
+ npy_intp PyArray_STRIDE(ndarray, size_t) nogil
+ PyObject *PyArray_BASE(ndarray) nogil # returns borrowed reference!
+ PyArray_Descr *PyArray_DESCR(ndarray) nogil # returns borrowed reference to dtype!
+ PyArray_Descr *PyArray_DTYPE(ndarray) nogil # returns borrowed reference to dtype! NP 1.7+ alias for descr.
+ int PyArray_FLAGS(ndarray) nogil
+ void PyArray_CLEARFLAGS(ndarray, int flags) nogil # Added in NumPy 1.7
+ void PyArray_ENABLEFLAGS(ndarray, int flags) nogil # Added in NumPy 1.7
+ npy_intp PyArray_ITEMSIZE(ndarray) nogil
+ int PyArray_TYPE(ndarray arr) nogil
+ object PyArray_GETITEM(ndarray arr, void *itemptr)
+ int PyArray_SETITEM(ndarray arr, void *itemptr, object obj)
+ bint PyTypeNum_ISBOOL(int) nogil
+ bint PyTypeNum_ISUNSIGNED(int) nogil
+ bint PyTypeNum_ISSIGNED(int) nogil
+ bint PyTypeNum_ISINTEGER(int) nogil
+ bint PyTypeNum_ISFLOAT(int) nogil
+ bint PyTypeNum_ISNUMBER(int) nogil
+ bint PyTypeNum_ISSTRING(int) nogil
+ bint PyTypeNum_ISCOMPLEX(int) nogil
+ bint PyTypeNum_ISPYTHON(int) nogil
+ bint PyTypeNum_ISFLEXIBLE(int) nogil
+ bint PyTypeNum_ISUSERDEF(int) nogil
+ bint PyTypeNum_ISEXTENDED(int) nogil
+ bint PyTypeNum_ISOBJECT(int) nogil
+ bint PyDataType_ISBOOL(dtype) nogil
+ bint PyDataType_ISUNSIGNED(dtype) nogil
+ bint PyDataType_ISSIGNED(dtype) nogil
+ bint PyDataType_ISINTEGER(dtype) nogil
+ bint PyDataType_ISFLOAT(dtype) nogil
+ bint PyDataType_ISNUMBER(dtype) nogil
+ bint PyDataType_ISSTRING(dtype) nogil
+ bint PyDataType_ISCOMPLEX(dtype) nogil
+ bint PyDataType_ISPYTHON(dtype) nogil
+ bint PyDataType_ISFLEXIBLE(dtype) nogil
+ bint PyDataType_ISUSERDEF(dtype) nogil
+ bint PyDataType_ISEXTENDED(dtype) nogil
+ bint PyDataType_ISOBJECT(dtype) nogil
+ bint PyDataType_HASFIELDS(dtype) nogil
+ bint PyDataType_HASSUBARRAY(dtype) nogil
+ bint PyArray_ISBOOL(ndarray) nogil
+ bint PyArray_ISUNSIGNED(ndarray) nogil
+ bint PyArray_ISSIGNED(ndarray) nogil
+ bint PyArray_ISINTEGER(ndarray) nogil
+ bint PyArray_ISFLOAT(ndarray) nogil
+ bint PyArray_ISNUMBER(ndarray) nogil
+ bint PyArray_ISSTRING(ndarray) nogil
+ bint PyArray_ISCOMPLEX(ndarray) nogil
+ bint PyArray_ISPYTHON(ndarray) nogil
+ bint PyArray_ISFLEXIBLE(ndarray) nogil
+ bint PyArray_ISUSERDEF(ndarray) nogil
+ bint PyArray_ISEXTENDED(ndarray) nogil
+ bint PyArray_ISOBJECT(ndarray) nogil
+ bint PyArray_HASFIELDS(ndarray) nogil
+ bint PyArray_ISVARIABLE(ndarray) nogil
+ bint PyArray_SAFEALIGNEDCOPY(ndarray) nogil
+ bint PyArray_ISNBO(char) nogil # works on ndarray.byteorder
+ bint PyArray_IsNativeByteOrder(char) nogil # works on ndarray.byteorder
+ bint PyArray_ISNOTSWAPPED(ndarray) nogil
+ bint PyArray_ISBYTESWAPPED(ndarray) nogil
+ bint PyArray_FLAGSWAP(ndarray, int) nogil
+ bint PyArray_ISCARRAY(ndarray) nogil
+ bint PyArray_ISCARRAY_RO(ndarray) nogil
+ bint PyArray_ISFARRAY(ndarray) nogil
+ bint PyArray_ISFARRAY_RO(ndarray) nogil
+ bint PyArray_ISBEHAVED(ndarray) nogil
+ bint PyArray_ISBEHAVED_RO(ndarray) nogil
+ bint PyDataType_ISNOTSWAPPED(dtype) nogil
+ bint PyDataType_ISBYTESWAPPED(dtype) nogil
+ bint PyArray_DescrCheck(object)
+ bint PyArray_Check(object)
+ bint PyArray_CheckExact(object)
+ # Cannot be supported due to out arg:
+ # bint PyArray_HasArrayInterfaceType(object, dtype, object, object&)
+ # bint PyArray_HasArrayInterface(op, out)
+ bint PyArray_IsZeroDim(object)
+ # Cannot be supported due to ## ## in macro:
+ # bint PyArray_IsScalar(object, verbatim work)
+ bint PyArray_CheckScalar(object)
+ bint PyArray_IsPythonNumber(object)
+ bint PyArray_IsPythonScalar(object)
+ bint PyArray_IsAnyScalar(object)
+ bint PyArray_CheckAnyScalar(object)
+ ndarray PyArray_GETCONTIGUOUS(ndarray)
+ bint PyArray_SAMESHAPE(ndarray, ndarray) nogil
+ npy_intp PyArray_SIZE(ndarray) nogil
+ npy_intp PyArray_NBYTES(ndarray) nogil
+ object PyArray_FROM_O(object)
+ object PyArray_FROM_OF(object m, int flags)
+ object PyArray_FROM_OT(object m, int type)
+ object PyArray_FROM_OTF(object m, int type, int flags)
+ object PyArray_FROMANY(object m, int type, int min, int max, int flags)
+ object PyArray_ZEROS(int nd, npy_intp* dims, int type, int fortran)
+ object PyArray_EMPTY(int nd, npy_intp* dims, int type, int fortran)
+ void PyArray_FILLWBYTE(object, int val)
+ npy_intp PyArray_REFCOUNT(object)
+ object PyArray_ContiguousFromAny(op, int, int min_depth, int max_depth)
+ unsigned char PyArray_EquivArrTypes(ndarray a1, ndarray a2)
+ bint PyArray_EquivByteorders(int b1, int b2) nogil
+ object PyArray_SimpleNew(int nd, npy_intp* dims, int typenum)
+ object PyArray_SimpleNewFromData(int nd, npy_intp* dims, int typenum, void* data)
+ #object PyArray_SimpleNewFromDescr(int nd, npy_intp* dims, dtype descr)
+ object PyArray_ToScalar(void* data, ndarray arr)
+ void* PyArray_GETPTR1(ndarray m, npy_intp i) nogil
+ void* PyArray_GETPTR2(ndarray m, npy_intp i, npy_intp j) nogil
+ void* PyArray_GETPTR3(ndarray m, npy_intp i, npy_intp j, npy_intp k) nogil
+ void* PyArray_GETPTR4(ndarray m, npy_intp i, npy_intp j, npy_intp k, npy_intp l) nogil
+ void PyArray_XDECREF_ERR(ndarray)
+ # Cannot be supported due to out arg
+ # void PyArray_DESCR_REPLACE(descr)
+ object PyArray_Copy(ndarray)
+ object PyArray_FromObject(object op, int type, int min_depth, int max_depth)
+ object PyArray_ContiguousFromObject(object op, int type, int min_depth, int max_depth)
+ object PyArray_CopyFromObject(object op, int type, int min_depth, int max_depth)
+ object PyArray_Cast(ndarray mp, int type_num)
+ object PyArray_Take(ndarray ap, object items, int axis)
+ object PyArray_Put(ndarray ap, object items, object values)
+ void PyArray_ITER_RESET(flatiter it) nogil
+ void PyArray_ITER_NEXT(flatiter it) nogil
+ void PyArray_ITER_GOTO(flatiter it, npy_intp* destination) nogil
+ void PyArray_ITER_GOTO1D(flatiter it, npy_intp ind) nogil
+ void* PyArray_ITER_DATA(flatiter it) nogil
+ bint PyArray_ITER_NOTDONE(flatiter it) nogil
+ void PyArray_MultiIter_RESET(broadcast multi) nogil
+ void PyArray_MultiIter_NEXT(broadcast multi) nogil
+ void PyArray_MultiIter_GOTO(broadcast multi, npy_intp dest) nogil
+ void PyArray_MultiIter_GOTO1D(broadcast multi, npy_intp ind) nogil
+ void* PyArray_MultiIter_DATA(broadcast multi, npy_intp i) nogil
+ void PyArray_MultiIter_NEXTi(broadcast multi, npy_intp i) nogil
+ bint PyArray_MultiIter_NOTDONE(broadcast multi) nogil
+ # Functions from __multiarray_api.h
+ # Functions taking dtype and returning object/ndarray are disabled
+ # for now as they steal dtype references. I'm conservative and disable
+ # more than is probably needed until it can be checked further.
+ int PyArray_SetNumericOps (object)
+ object PyArray_GetNumericOps ()
+ int PyArray_INCREF (ndarray)
+ int PyArray_XDECREF (ndarray)
+ void PyArray_SetStringFunction (object, int)
+ dtype PyArray_DescrFromType (int)
+ object PyArray_TypeObjectFromType (int)
+ char * PyArray_Zero (ndarray)
+ char * PyArray_One (ndarray)
+ #object PyArray_CastToType (ndarray, dtype, int)
+ int PyArray_CastTo (ndarray, ndarray)
+ int PyArray_CastAnyTo (ndarray, ndarray)
+ int PyArray_CanCastSafely (int, int)
+ npy_bool PyArray_CanCastTo (dtype, dtype)
+ int PyArray_ObjectType (object, int)
+ dtype PyArray_DescrFromObject (object, dtype)
+ #ndarray* PyArray_ConvertToCommonType (object, int *)
+ dtype PyArray_DescrFromScalar (object)
+ dtype PyArray_DescrFromTypeObject (object)
+ npy_intp PyArray_Size (object)
+ #object PyArray_Scalar (void *, dtype, object)
+ #object PyArray_FromScalar (object, dtype)
+ void PyArray_ScalarAsCtype (object, void *)
+ #int PyArray_CastScalarToCtype (object, void *, dtype)
+ #int PyArray_CastScalarDirect (object, dtype, void *, int)
+ object PyArray_ScalarFromObject (object)
+ #PyArray_VectorUnaryFunc * PyArray_GetCastFunc (dtype, int)
+ object PyArray_FromDims (int, int *, int)
+ #object PyArray_FromDimsAndDataAndDescr (int, int *, dtype, char *)
+ #object PyArray_FromAny (object, dtype, int, int, int, object)
+ object PyArray_EnsureArray (object)
+ object PyArray_EnsureAnyArray (object)
+ #object PyArray_FromFile (stdio.FILE *, dtype, npy_intp, char *)
+ #object PyArray_FromString (char *, npy_intp, dtype, npy_intp, char *)
+ #object PyArray_FromBuffer (object, dtype, npy_intp, npy_intp)
+ #object PyArray_FromIter (object, dtype, npy_intp)
+ object PyArray_Return (ndarray)
+ #object PyArray_GetField (ndarray, dtype, int)
+ #int PyArray_SetField (ndarray, dtype, int, object)
+ object PyArray_Byteswap (ndarray, npy_bool)
+ object PyArray_Resize (ndarray, PyArray_Dims *, int, NPY_ORDER)
+ int PyArray_MoveInto (ndarray, ndarray)
+ int PyArray_CopyInto (ndarray, ndarray)
+ int PyArray_CopyAnyInto (ndarray, ndarray)
+ int PyArray_CopyObject (ndarray, object)
+ object PyArray_NewCopy (ndarray, NPY_ORDER)
+ object PyArray_ToList (ndarray)
+ object PyArray_ToString (ndarray, NPY_ORDER)
+ int PyArray_ToFile (ndarray, stdio.FILE *, char *, char *)
+ int PyArray_Dump (object, object, int)
+ object PyArray_Dumps (object, int)
+ int PyArray_ValidType (int)
+ void PyArray_UpdateFlags (ndarray, int)
+ object PyArray_New (type, int, npy_intp *, int, npy_intp *, void *, int, int, object)
+ #object PyArray_NewFromDescr (type, dtype, int, npy_intp *, npy_intp *, void *, int, object)
+ #dtype PyArray_DescrNew (dtype)
+ dtype PyArray_DescrNewFromType (int)
+ double PyArray_GetPriority (object, double)
+ object PyArray_IterNew (object)
+ object PyArray_MultiIterNew (int, ...)
+ int PyArray_PyIntAsInt (object)
+ npy_intp PyArray_PyIntAsIntp (object)
+ int PyArray_Broadcast (broadcast)
+ void PyArray_FillObjectArray (ndarray, object)
+ int PyArray_FillWithScalar (ndarray, object)
+ npy_bool PyArray_CheckStrides (int, int, npy_intp, npy_intp, npy_intp *, npy_intp *)
+ dtype PyArray_DescrNewByteorder (dtype, char)
+ object PyArray_IterAllButAxis (object, int *)
+ #object PyArray_CheckFromAny (object, dtype, int, int, int, object)
+ #object PyArray_FromArray (ndarray, dtype, int)
+ object PyArray_FromInterface (object)
+ object PyArray_FromStructInterface (object)
+ #object PyArray_FromArrayAttr (object, dtype, object)
+ #NPY_SCALARKIND PyArray_ScalarKind (int, ndarray*)
+ int PyArray_CanCoerceScalar (int, int, NPY_SCALARKIND)
+ object PyArray_NewFlagsObject (object)
+ npy_bool PyArray_CanCastScalar (type, type)
+ #int PyArray_CompareUCS4 (npy_ucs4 *, npy_ucs4 *, register size_t)
+ int PyArray_RemoveSmallest (broadcast)
+ int PyArray_ElementStrides (object)
+ void PyArray_Item_INCREF (char *, dtype)
+ void PyArray_Item_XDECREF (char *, dtype)
+ object PyArray_FieldNames (object)
+ object PyArray_Transpose (ndarray, PyArray_Dims *)
+ object PyArray_TakeFrom (ndarray, object, int, ndarray, NPY_CLIPMODE)
+ object PyArray_PutTo (ndarray, object, object, NPY_CLIPMODE)
+ object PyArray_PutMask (ndarray, object, object)
+ object PyArray_Repeat (ndarray, object, int)
+ object PyArray_Choose (ndarray, object, ndarray, NPY_CLIPMODE)
+ int PyArray_Sort (ndarray, int, NPY_SORTKIND)
+ object PyArray_ArgSort (ndarray, int, NPY_SORTKIND)
+ object PyArray_SearchSorted (ndarray, object, NPY_SEARCHSIDE, PyObject *)
+ object PyArray_ArgMax (ndarray, int, ndarray)
+ object PyArray_ArgMin (ndarray, int, ndarray)
+ object PyArray_Reshape (ndarray, object)
+ object PyArray_Newshape (ndarray, PyArray_Dims *, NPY_ORDER)
+ object PyArray_Squeeze (ndarray)
+ #object PyArray_View (ndarray, dtype, type)
+ object PyArray_SwapAxes (ndarray, int, int)
+ object PyArray_Max (ndarray, int, ndarray)
+ object PyArray_Min (ndarray, int, ndarray)
+ object PyArray_Ptp (ndarray, int, ndarray)
+ object PyArray_Mean (ndarray, int, int, ndarray)
+ object PyArray_Trace (ndarray, int, int, int, int, ndarray)
+ object PyArray_Diagonal (ndarray, int, int, int)
+ object PyArray_Clip (ndarray, object, object, ndarray)
+ object PyArray_Conjugate (ndarray, ndarray)
+ object PyArray_Nonzero (ndarray)
+ object PyArray_Std (ndarray, int, int, ndarray, int)
+ object PyArray_Sum (ndarray, int, int, ndarray)
+ object PyArray_CumSum (ndarray, int, int, ndarray)
+ object PyArray_Prod (ndarray, int, int, ndarray)
+ object PyArray_CumProd (ndarray, int, int, ndarray)
+ object PyArray_All (ndarray, int, ndarray)
+ object PyArray_Any (ndarray, int, ndarray)
+ object PyArray_Compress (ndarray, object, int, ndarray)
+ object PyArray_Flatten (ndarray, NPY_ORDER)
+ object PyArray_Ravel (ndarray, NPY_ORDER)
+ npy_intp PyArray_MultiplyList (npy_intp *, int)
+ int PyArray_MultiplyIntList (int *, int)
+ void * PyArray_GetPtr (ndarray, npy_intp*)
+ int PyArray_CompareLists (npy_intp *, npy_intp *, int)
+ #int PyArray_AsCArray (object*, void *, npy_intp *, int, dtype)
+ #int PyArray_As1D (object*, char **, int *, int)
+ #int PyArray_As2D (object*, char ***, int *, int *, int)
+ int PyArray_Free (object, void *)
+ #int PyArray_Converter (object, object*)
+ int PyArray_IntpFromSequence (object, npy_intp *, int)
+ object PyArray_Concatenate (object, int)
+ object PyArray_InnerProduct (object, object)
+ object PyArray_MatrixProduct (object, object)
+ object PyArray_CopyAndTranspose (object)
+ object PyArray_Correlate (object, object, int)
+ int PyArray_TypestrConvert (int, int)
+ #int PyArray_DescrConverter (object, dtype*)
+ #int PyArray_DescrConverter2 (object, dtype*)
+ int PyArray_IntpConverter (object, PyArray_Dims *)
+ #int PyArray_BufferConverter (object, chunk)
+ int PyArray_AxisConverter (object, int *)
+ int PyArray_BoolConverter (object, npy_bool *)
+ int PyArray_ByteorderConverter (object, char *)
+ int PyArray_OrderConverter (object, NPY_ORDER *)
+ unsigned char PyArray_EquivTypes (dtype, dtype)
+ #object PyArray_Zeros (int, npy_intp *, dtype, int)
+ #object PyArray_Empty (int, npy_intp *, dtype, int)
+ object PyArray_Where (object, object, object)
+ object PyArray_Arange (double, double, double, int)
+ #object PyArray_ArangeObj (object, object, object, dtype)
+ int PyArray_SortkindConverter (object, NPY_SORTKIND *)
+ object PyArray_LexSort (object, int)
+ object PyArray_Round (ndarray, int, ndarray)
+ unsigned char PyArray_EquivTypenums (int, int)
+ int PyArray_RegisterDataType (dtype)
+ int PyArray_RegisterCastFunc (dtype, int, PyArray_VectorUnaryFunc *)
+ int PyArray_RegisterCanCast (dtype, int, NPY_SCALARKIND)
+ #void PyArray_InitArrFuncs (PyArray_ArrFuncs *)
+ object PyArray_IntTupleFromIntp (int, npy_intp *)
+ int PyArray_TypeNumFromName (char *)
+ int PyArray_ClipmodeConverter (object, NPY_CLIPMODE *)
+ #int PyArray_OutputConverter (object, ndarray*)
+ object PyArray_BroadcastToShape (object, npy_intp *, int)
+ void _PyArray_SigintHandler (int)
+ void* _PyArray_GetSigintBuf ()
+ #int PyArray_DescrAlignConverter (object, dtype*)
+ #int PyArray_DescrAlignConverter2 (object, dtype*)
+ int PyArray_SearchsideConverter (object, void *)
+ object PyArray_CheckAxis (ndarray, int *, int)
+ npy_intp PyArray_OverflowMultiplyList (npy_intp *, int)
+ int PyArray_CompareString (char *, char *, size_t)
+ int PyArray_SetBaseObject(ndarray, base) # NOTE: steals a reference to base! Use "set_array_base()" instead.
+# Typedefs that matches the runtime dtype objects in
+# the numpy module.
+# The ones that are commented out needs an IFDEF function
+# in Cython to enable them only on the right systems.
+ctypedef npy_int8 int8_t
+ctypedef npy_int16 int16_t
+ctypedef npy_int32 int32_t
+ctypedef npy_int64 int64_t
+#ctypedef npy_int96 int96_t
+#ctypedef npy_int128 int128_t
+ctypedef npy_uint8 uint8_t
+ctypedef npy_uint16 uint16_t
+ctypedef npy_uint32 uint32_t
+ctypedef npy_uint64 uint64_t
+#ctypedef npy_uint96 uint96_t
+#ctypedef npy_uint128 uint128_t
+ctypedef npy_float32 float32_t
+ctypedef npy_float64 float64_t
+#ctypedef npy_float80 float80_t
+#ctypedef npy_float128 float128_t
+ctypedef float complex complex64_t
+ctypedef double complex complex128_t
+# The int types are mapped a bit surprising --
+# numpy.int corresponds to 'l' and numpy.long to 'q'
+ctypedef npy_long int_t
+ctypedef npy_longlong long_t
+ctypedef npy_longlong longlong_t
+ctypedef npy_ulong uint_t
+ctypedef npy_ulonglong ulong_t
+ctypedef npy_ulonglong ulonglong_t
+ctypedef npy_intp intp_t
+ctypedef npy_uintp uintp_t
+ctypedef npy_double float_t
+ctypedef npy_double double_t
+ctypedef npy_longdouble longdouble_t
+ctypedef npy_cfloat cfloat_t
+ctypedef npy_cdouble cdouble_t
+ctypedef npy_clongdouble clongdouble_t
+ctypedef npy_cdouble complex_t
+cdef inline object PyArray_MultiIterNew1(a):
+ return PyArray_MultiIterNew(1, <void*>a)
+cdef inline object PyArray_MultiIterNew2(a, b):
+ return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+cdef inline object PyArray_MultiIterNew3(a, b, c):
+ return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+cdef inline object PyArray_MultiIterNew4(a, b, c, d):
+ return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
+ return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+cdef inline tuple PyDataType_SHAPE(dtype d):
+ if PyDataType_HASSUBARRAY(d):
+ return <tuple>d.subarray.shape
+ return ()
+cdef extern from "numpy/ndarrayobject.h":
+ PyTypeObject PyTimedeltaArrType_Type
+ PyTypeObject PyDatetimeArrType_Type
+ ctypedef int64_t npy_timedelta
+ ctypedef int64_t npy_datetime
+cdef extern from "numpy/ndarraytypes.h":
+ ctypedef struct PyArray_DatetimeMetaData:
+ NPY_DATETIMEUNIT base
+ int64_t num
+cdef extern from "numpy/arrayscalars.h":
+ # abstract types
+ ctypedef class numpy.generic [object PyObject]:
+ ctypedef class numpy.number [object PyObject]:
+ ctypedef class numpy.integer [object PyObject]:
+ ctypedef class numpy.signedinteger [object PyObject]:
+ ctypedef class numpy.unsignedinteger [object PyObject]:
+ ctypedef class numpy.inexact [object PyObject]:
+ ctypedef class numpy.floating [object PyObject]:
+ ctypedef class numpy.complexfloating [object PyObject]:
+ ctypedef class numpy.flexible [object PyObject]:
+ ctypedef class numpy.character [object PyObject]:
+ ctypedef struct PyDatetimeScalarObject:
+ # PyObject_HEAD
+ npy_datetime obval
+ PyArray_DatetimeMetaData obmeta
+ ctypedef struct PyTimedeltaScalarObject:
+ npy_timedelta obval
+ ctypedef enum NPY_DATETIMEUNIT:
+ NPY_FR_Y
+ NPY_FR_M
+ NPY_FR_W
+ NPY_FR_D
+ NPY_FR_B
+ NPY_FR_h
+ NPY_FR_m
+ NPY_FR_s
+ NPY_FR_ms
+ NPY_FR_us
+ NPY_FR_ns
+ NPY_FR_ps
+ NPY_FR_fs
+ NPY_FR_as
+# ufunc API
+cdef extern from "numpy/ufuncobject.h":
+ ctypedef void (*PyUFuncGenericFunction) (char **, npy_intp *, npy_intp *, void *)
+ ctypedef class numpy.ufunc [object PyUFuncObject, check_size ignore]:
+ cdef:
+ int nin, nout, nargs
+ int identity
+ PyUFuncGenericFunction *functions
+ void **data
+ int ntypes
+ int check_return
+ char *name
+ char *types
+ char *doc
+ void *ptr
+ PyObject *obj
+ PyObject *userloops
+ PyUFunc_Zero
+ PyUFunc_One
+ PyUFunc_None
+ UFUNC_ERR_IGNORE
+ UFUNC_ERR_WARN
+ UFUNC_ERR_RAISE
+ UFUNC_ERR_CALL
+ UFUNC_ERR_PRINT
+ UFUNC_ERR_LOG
+ UFUNC_MASK_DIVIDEBYZERO
+ UFUNC_MASK_OVERFLOW
+ UFUNC_MASK_UNDERFLOW
+ UFUNC_MASK_INVALID
+ UFUNC_SHIFT_DIVIDEBYZERO
+ UFUNC_SHIFT_OVERFLOW
+ UFUNC_SHIFT_UNDERFLOW
+ UFUNC_SHIFT_INVALID
+ UFUNC_FPE_DIVIDEBYZERO
+ UFUNC_FPE_OVERFLOW
+ UFUNC_FPE_UNDERFLOW
+ UFUNC_FPE_INVALID
+ UFUNC_ERR_DEFAULT
+ UFUNC_ERR_DEFAULT2
+ object PyUFunc_FromFuncAndData(PyUFuncGenericFunction *,
+ 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 \
+ void PyUFunc_f_f \
+ void PyUFunc_g_g \
+ void PyUFunc_F_F_As_D_D \
+ void PyUFunc_F_F \
+ void PyUFunc_D_D \
+ void PyUFunc_G_G \
+ void PyUFunc_O_O \
+ void PyUFunc_ff_f_As_dd_d \
+ void PyUFunc_ff_f \
+ void PyUFunc_dd_d \
+ void PyUFunc_gg_g \
+ void PyUFunc_FF_F_As_DD_D \
+ void PyUFunc_DD_D \
+ void PyUFunc_FF_F \
+ void PyUFunc_GG_G \
+ void PyUFunc_OO_O \
+ void PyUFunc_O_O_method \
+ void PyUFunc_OO_O_method \
+ void PyUFunc_On_Om \
+ int PyUFunc_GetPyValues \
+ (char *, int *, int *, PyObject **)
+ int PyUFunc_checkfperr \
+ (int, PyObject *, int *)
+ void PyUFunc_clearfperr()
+ int PyUFunc_getfperr()
+ int PyUFunc_handlefperr \
+ (int, PyObject *, int, int *)
+ int PyUFunc_ReplaceLoopBySignature \
+ (ufunc, PyUFuncGenericFunction, int *, PyUFuncGenericFunction *)
+ object PyUFunc_FromFuncAndDataAndSignature \
+ (PyUFuncGenericFunction *, void **, char *, int, int, int,
+ int, char *, char *, int, char *)
+ int _import_umath() except -1
+cdef inline void set_array_base(ndarray arr, object base):
+ Py_INCREF(base) # important to do this before stealing the reference below!
+ PyArray_SetBaseObject(arr, base)
+cdef inline object get_array_base(ndarray arr):
+ base = PyArray_BASE(arr)
+ if base is NULL:
+ return None
+ return <object>base
+# Versions of the import_* functions which are more suitable for
+# Cython code.
+cdef inline int import_array() except -1:
+ try:
+ __pyx_import_array()
+ except Exception:
+ raise ImportError("numpy.core.multiarray failed to import")
+cdef inline int import_umath() except -1:
+ _import_umath()
+ raise ImportError("numpy.core.umath failed to import")
+cdef inline int import_ufunc() except -1:
+cdef inline bint is_timedelta64_object(object obj):
+ Cython equivalent of `isinstance(obj, np.timedelta64)`
+ Parameters
+ ----------
+ obj : object
+ Returns
+ -------
+ bool
+ return PyObject_TypeCheck(obj, &PyTimedeltaArrType_Type)
+cdef inline bint is_datetime64_object(object obj):
+ Cython equivalent of `isinstance(obj, np.datetime64)`
+ return PyObject_TypeCheck(obj, &PyDatetimeArrType_Type)
+cdef inline npy_datetime get_datetime64_value(object obj) nogil:
+ returns the int64 value underlying scalar numpy datetime64 object
+ Note that to interpret this as a datetime, the corresponding unit is
+ also needed. That can be found using `get_datetime64_unit`.
+ return (<PyDatetimeScalarObject*>obj).obval
+cdef inline npy_timedelta get_timedelta64_value(object obj) nogil:
+ returns the int64 value underlying scalar numpy timedelta64 object
+ return (<PyTimedeltaScalarObject*>obj).obval
+cdef inline NPY_DATETIMEUNIT get_datetime64_unit(object obj) nogil:
+ returns the unit part of the dtype for a numpy datetime64 object.
+ return <NPY_DATETIMEUNIT>(<PyDatetimeScalarObject*>obj).obmeta.base
@@ -0,0 +1,1020 @@
+# NumPy static imports for Cython < 3.0
+# called first.
+DEF _buffer_format_string_len = 255
+cimport cpython.buffer as pybuf
+from cpython.mem cimport PyObject_Malloc, PyObject_Free
+from cpython.object cimport PyObject, PyTypeObject
+from cpython.buffer cimport PyObject_GetBuffer
+from cpython.type cimport type
+ ctypedef int Py_intptr_t
+ bint PyObject_TypeCheck(object obj, PyTypeObject* type)
+ cdef int numiter
+ cdef npy_intp size, index
+ cdef int nd
+ cdef npy_intp *dimensions
+ cdef void **iters
+ # Only taking a few of the most commonly used and stable fields.
+ # One should use PyArray_* macros instead to access the C fields.
+ char *data
+ int ndim "nd"
+ npy_intp *shape "dimensions"
+ npy_intp *strides
+ dtype descr # deprecated since NumPy 1.7 !
+ PyObject* base # NOT PUBLIC, DO NOT USE !
+ # Leave a marker that the NumPy declarations came from this file
+ /* NumPy API declarations from "numpy/__init__.pxd" */
@@ -0,0 +1,410 @@
+"""
+NumPy
+=====
+Provides
+ 1. An array object of arbitrary homogeneous items
+ 2. Fast mathematical operations over arrays
+ 3. Linear Algebra, Fourier Transforms, Random Number Generation
+How to use the documentation
+----------------------------
+Documentation is available in two forms: docstrings provided
+with the code, and a loose standing reference guide, available from
+`the NumPy homepage <https://www.scipy.org>`_.
+We recommend exploring the docstrings using
+`IPython <https://ipython.org>`_, an advanced Python shell with
+TAB-completion and introspection capabilities. See below for further
+instructions.
+The docstring examples assume that `numpy` has been imported as `np`::
+Code snippets are indicated by three greater-than signs::
+ >>> x = 42
+ >>> x = x + 1
+Use the built-in ``help`` function to view a function's docstring::
+ >>> help(np.sort)
+ ... # doctest: +SKIP
+For some objects, ``np.info(obj)`` may provide additional help. This is
+particularly true if you see the line "Help on ufunc object:" at the top
+of the help() page. Ufuncs are implemented in C, not Python, for speed.
+The native Python help() does not know how to view their help, but our
+np.info() function does.
+To search for documents containing a keyword, do::
+ >>> np.lookfor('keyword')
+General-purpose documents like a glossary and help on the basic concepts
+of numpy are available under the ``doc`` sub-module::
+ >>> from numpy import doc
+ >>> help(doc)
+Available subpackages
+---------------------
+doc
+ Topical documentation on broadcasting, indexing, etc.
+lib
+ Basic functions used by several sub-packages.
+random
+ Core Random Tools
+linalg
+ Core Linear Algebra Tools
+fft
+ Core FFT routines
+polynomial
+ Polynomial tools
+testing
+ NumPy testing tools
+f2py
+ Fortran to Python Interface Generator.
+distutils
+ Enhancements to distutils with support for
+ Fortran compilers support and more.
+Utilities
+---------
+test
+ Run numpy unittests
+show_config
+ Show numpy build configuration
+dual
+ Overwrite certain functions with high-performance SciPy tools.
+ Note: `numpy.dual` is deprecated. Use the functions from NumPy or Scipy
+ directly instead of importing them from `numpy.dual`.
+matlib
+ Make everything matrices.
+__version__
+ NumPy version string
+Viewing documentation using IPython
+-----------------------------------
+Start IPython with the NumPy profile (``ipython -p numpy``), which will
+import `numpy` under the alias `np`. Then, use the ``cpaste`` command to
+paste examples into the shell. To see which functions are available in
+`numpy`, type ``np.<TAB>`` (where ``<TAB>`` refers to the TAB key), or use
+``np.*cos*?<ENTER>`` (where ``<ENTER>`` refers to the ENTER key) to narrow
+down the list. To view the docstring for a function, use
+``np.cos?<ENTER>`` (to view the docstring) and ``np.cos??<ENTER>`` (to view
+the source code).
+Copies vs. in-place operation
+-----------------------------
+Most of the functions in `numpy` return a copy of the array argument
+(e.g., `np.sort`). In-place versions of these functions are often
+available as array methods, i.e. ``x = np.array([1,2,3]); x.sort()``.
+Exceptions to this rule are documented.
+import warnings
+from ._globals import ModuleDeprecationWarning, VisibleDeprecationWarning
+from ._globals import _NoValue
+# We first need to detect if we're being called as part of the numpy setup
+# procedure itself in a reliable manner.
+try:
+ __NUMPY_SETUP__
+except NameError:
+ __NUMPY_SETUP__ = False
+if __NUMPY_SETUP__:
+ sys.stderr.write('Running from numpy source directory.\n')
+else:
+ from numpy.__config__ import show as show_config
+ except ImportError as e:
+ msg = """Error importing numpy: you should not try to import numpy from
+ its source directory; please exit the numpy source tree, and relaunch
+ 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']
+ # mapping of {name: (value, deprecation_msg)}
+ __deprecated_attrs__ = {}
+ # Allow distributors to run custom init code
+ from . import _distributor_init
+ from . import core
+ from .core import *
+ from . import compat
+ from . import lib
+ # NOTE: to be revisited following future namespace cleanup.
+ # See gh-14454 and gh-15672 for discussion.
+ from .lib import *
+ from . import linalg
+ from . import fft
+ from . import polynomial
+ from . import random
+ from . import ctypeslib
+ from . import ma
+ from . import matrixlib as _mat
+ from .matrixlib import *
+ # 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), _msg.format(n=n, extended_msg=extended_msg))
+ for n, extended_msg in _type_info
+ })
+ "`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_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
+ core.getlimits._register_known_types()
+ __all__.extend(['__version__', 'show_config'])
+ __all__.extend(core.__all__)
+ __all__.extend(_mat.__all__)
+ __all__.extend(lib.__all__)
+ __all__.extend(['linalg', 'fft', 'random', 'ctypeslib', 'ma'])
+ # These are exported by np.core, but are replaced by the builtins below
+ # remove them to ensure that we don't end up with `np.long == np.int_`,
+ # which would be a breaking change.
+ del long, unicode
+ __all__.remove('long')
+ __all__.remove('unicode')
+ # Remove things that are in the numpy.lib but not in the numpy namespace
+ # Note that there is a test (numpy/tests/test_public_api.py:test_numpy_namespace)
+ # that prevents adding more things to the main namespace by accident.
+ # The list below will grow until the `from .lib import *` fixme above is
+ # taken care of
+ __all__.remove('Arrayterator')
+ del Arrayterator
+ # These names were removed in NumPy 1.20. For at least one release,
+ # attempts to access these names in the numpy namespace will trigger
+ # a warning, and calling the function will raise an exception.
+ _financial_names = ['fv', 'ipmt', 'irr', 'mirr', 'nper', 'npv', 'pmt',
+ 'ppmt', 'pv', 'rate']
+ __expired_functions__ = {
+ name: (f'In accordance with NEP 32, the function {name} was removed '
+ 'from NumPy version 1.20. A replacement for this function '
+ 'is available in the numpy_financial library: '
+ 'https://pypi.org/project/numpy-financial')
+ for name in _financial_names}
+ # Filter out Cython harmless warnings
+ warnings.filterwarnings("ignore", message="numpy.dtype size changed")
+ warnings.filterwarnings("ignore", message="numpy.ufunc size changed")
+ warnings.filterwarnings("ignore", message="numpy.ndarray size changed")
+ # oldnumeric and numarray were removed in 1.9. In case some packages import
+ # but do not use them, we define them here for backward compatibility.
+ oldnumeric = 'removed'
+ numarray = 'removed'
+ 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/
+ def __getattr__(attr):
+ # Warn for expired attributes, and return a dummy function
+ # that always raises an exception.
+ msg = __expired_functions__[attr]
+ except KeyError:
+ warnings.warn(msg, DeprecationWarning, stacklevel=2)
+ def _expired(*args, **kwds):
+ raise RuntimeError(msg)
+ return _expired
+ # Emit warnings for deprecated attributes
+ val, msg = __deprecated_attrs__[attr]
+ return val
+ # Importing Tester requires importing all of UnitTest which is not a
+ # cheap import Since it is mainly used in test suits, we lazy import it
+ # here to save on the order of 10 ms of import time for most users
+ # The previous way Tester was imported also had a side effect of adding
+ # the full `numpy.testing` namespace
+ if attr == 'testing':
+ import numpy.testing as testing
+ return testing
+ elif attr == 'Tester':
+ from .testing import Tester
+ return Tester
+ raise AttributeError("module {!r} has no attribute "
+ "{!r}".format(__name__, attr))
+ def __dir__():
+ return list(globals().keys() | {'Tester', 'testing'})
+ # We don't actually use this ourselves anymore, but I'm not 100% sure that
+ # no-one else in the world is using it (though I hope not)
+ # We weren't able to emit a warning about these, so keep them around
+ globals().update({
+ k: v
+ for k, (v, msg) in __deprecated_attrs__.items()
+ # Pytest testing
+ from numpy._pytesttester import PytestTester
+ test = PytestTester(__name__)
+ del PytestTester
+ def _sanity_check():
+ Quick sanity checks for common bugs caused by environment.
+ There are some cases e.g. with wrong BLAS ABI that cause wrong
+ results under specific runtime conditions that are not necessarily
+ achieved during test suite runs, and it is useful to catch those early.
+ See https://github.com/numpy/numpy/issues/8577 and other
+ similar bug reports.
+ x = ones(2, dtype=float32)
+ if not abs(x.dot(x) - 2.0) < 1e-5:
+ raise AssertionError()
+ except AssertionError:
+ msg = ("The current Numpy installation ({!r}) fails to "
+ "pass simple sanity checks. This can be caused for example "
+ "by incorrect BLAS library being linked in, or by mixing "
+ "package managers (pip, conda, apt, ...). Search closed "
+ "numpy issues for similar problems.")
+ raise RuntimeError(msg.format(__file__)) from None
+ _sanity_check()
+ del _sanity_check
+ def _mac_os_check():
+ Quick Sanity check for Mac OS look for accelerate build bugs.
+ Testing numpy polyfit calls init_dgelsd(LAPACK)
+ c = array([3., 2., 1.])
+ x = linspace(0, 2, 5)
+ y = polyval(c, x)
+ _ = polyfit(x, y, 2, cov=True)
+ except ValueError:
+ import sys
+ if sys.platform == "darwin":
+ with warnings.catch_warnings(record=True) as w:
+ _mac_os_check()
+ # Throw runtime error, if the test failed Check for warning and error_message
+ error_message = ""
+ if len(w) > 0:
+ 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 "
+ "that provided NumPy.\n{}\n".format(error_message))
+ del _mac_os_check
+ # We usually use madvise hugepages support, but on some old kernels it
+ # is slow and thus better avoided.
+ # Specifically kernel version 4.6 had a bug fix which probably fixed this:
+ # https://github.com/torvalds/linux/commit/7cf91a98e607c2f935dbcc177d70011e95b8faff
+ import os
+ use_hugepage = os.environ.get("NUMPY_MADVISE_HUGEPAGE", None)
+ if sys.platform == "linux" and use_hugepage is None:
+ # If there is an issue with parsing the kernel version,
+ # set use_hugepages to 0. Usage of LooseVersion will handle
+ # the kernel version parsing better, but avoided since it
+ # will increase the import time. See: #16679 for related discussion.
+ use_hugepage = 1
+ kernel_version = os.uname().release.split(".")[:2]
+ kernel_version = tuple(int(v) for v in kernel_version)
+ if kernel_version < (4, 6):
+ use_hugepage = 0
+ use_hugepages = 0
+ elif use_hugepage is None:
+ # This is not Linux, so it should not matter, just enable anyway
+ use_hugepage = int(use_hugepage)
+ # Note that this will currently only make a difference on Linux
+ core.multiarray._set_madvise_hugepage(use_hugepage)
@@ -0,0 +1,2260 @@
+import builtins
+import datetime as dt
+from abc import abstractmethod
+from types import TracebackType
+from contextlib import ContextDecorator
+from numpy.core._internal import _ctypes
+from numpy.typing import (
+ ArrayLike,
+ DTypeLike,
+ _Shape,
+ _ShapeLike,
+ _CharLike,
+ _BoolLike,
+ _IntLike,
+ _FloatLike,
+ _ComplexLike,
+ _NumberLike,
+ _SupportsDType,
+ _VoidDTypeLike,
+ NBitBase,
+ _64Bit,
+ _32Bit,
+ _16Bit,
+ _8Bit,
+)
+from numpy.typing._callable import (
+ _BoolOp,
+ _BoolBitOp,
+ _BoolSub,
+ _BoolTrueDiv,
+ _BoolMod,
+ _BoolDivMod,
+ _TD64Div,
+ _IntTrueDiv,
+ _UnsignedIntOp,
+ _UnsignedIntBitOp,
+ _UnsignedIntMod,
+ _UnsignedIntDivMod,
+ _SignedIntOp,
+ _SignedIntBitOp,
+ _SignedIntMod,
+ _SignedIntDivMod,
+ _FloatOp,
+ _FloatMod,
+ _FloatDivMod,
+ _ComplexOp,
+ _NumberOp,
+from typing import (
+ Any,
+ ByteString,
+ Callable,
+ Container,
+ Dict,
+ Generic,
+ IO,
+ Iterable,
+ List,
+ Mapping,
+ Optional,
+ overload,
+ Sequence,
+ Sized,
+ SupportsComplex,
+ SupportsFloat,
+ SupportsInt,
+ Text,
+ Tuple,
+ Type,
+ TypeVar,
+ Union,
+if sys.version_info >= (3, 8):
+ from typing import Literal, Protocol, SupportsIndex, Final
+ from typing_extensions import Literal, Protocol, Final
+ class SupportsIndex(Protocol):
+ def __index__(self) -> int: ...
+# Ensures that the stubs are picked up
+from numpy import (
+ char as char,
+ ctypeslib as ctypeslib,
+ emath as emath,
+ 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 as linspace,
+ logspace as logspace,
+ geomspace as geomspace,
+from numpy.core.fromnumeric import (
+ 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,
+from numpy.core._type_aliases import (
+ sctypes as sctypes,
+ sctypeDict as sctypeDict,
+from numpy.core._ufunc_config import (
+ seterr as seterr,
+ geterr as geterr,
+ setbufsize as setbufsize,
+ getbufsize as getbufsize,
+ seterrcall as seterrcall,
+ geterrcall as geterrcall,
+ _SupportsWrite,
+ _ErrKind,
+ _ErrFunc,
+ _ErrDictOptional,
+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,
+ isfortran as isfortran,
+ argwhere as argwhere,
+ flatnonzero as flatnonzero,
+ correlate as correlate,
+ convolve as convolve,
+ outer as outer,
+ tensordot as tensordot,
+ roll as roll,
+ rollaxis as rollaxis,
+ moveaxis as moveaxis,
+ cross as cross,
+ indices as indices,
+ fromfunction as fromfunction,
+ isscalar as isscalar,
+ binary_repr as binary_repr,
+ base_repr as base_repr,
+ identity as identity,
+ allclose as allclose,
+ isclose as isclose,
+ array_equal as array_equal,
+ array_equiv as array_equiv,
+from numpy.core.numerictypes import (
+ maximum_sctype as maximum_sctype,
+ issctype as issctype,
+ obj2sctype as obj2sctype,
+ issubclass_ as issubclass_,
+ issubsctype as issubsctype,
+ issubdtype as issubdtype,
+ sctype2char as sctype2char,
+ find_common_type as find_common_type,
+from numpy.core.shape_base import (
+ atleast_1d as atleast_1d,
+ atleast_2d as atleast_2d,
+ atleast_3d as atleast_3d,
+ block as block,
+ hstack as hstack,
+ stack as stack,
+ vstack as vstack,
+__all__: List[str]
+__path__: List[str]
+__version__: str
+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
+_NdArraySubClass = TypeVar("_NdArraySubClass", bound=ndarray)
+_DTypeScalar = TypeVar("_DTypeScalar", bound=generic)
+_ByteOrder = Literal["S", "<", ">", "=", "|", "L", "B", "N", "I"]
+class dtype(Generic[_DTypeScalar]):
+ names: Optional[Tuple[str, ...]]
+ # Overload for subclass of generic
+ @overload
+ def __new__(
+ cls,
+ dtype: Type[_DTypeScalar],
+ align: bool = ...,
+ copy: bool = ...,
+ ) -> dtype[_DTypeScalar]: ...
+ # 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
+ # so we have to make sure the overloads for the narrowest type is
+ # first.
+ dtype: Union[
+ Type[bool],
+ Literal[
+ "?",
+ "=?",
+ "<?",
+ ">?",
+ "bool",
+ "bool_",
+ ) -> dtype[bool_]: ...
+ dtype: Literal[
+ "uint8",
+ "u1",
+ "=u1",
+ "<u1",
+ ">u1",
+ ) -> dtype[uint8]: ...
+ "uint16",
+ "u2",
+ "=u2",
+ "<u2",
+ ">u2",
+ ) -> dtype[uint16]: ...
+ "uint32",
+ "u4",
+ "=u4",
+ "<u4",
+ ">u4",
+ ) -> dtype[uint32]: ...
+ "uint64",
+ "u8",
+ "=u8",
+ "<u8",
+ ">u8",
+ ) -> dtype[uint64]: ...
+ "int8",
+ "i1",
+ "=i1",
+ "<i1",
+ ">i1",
+ ) -> dtype[int8]: ...
+ "int16",
+ "i2",
+ "=i2",
+ "<i2",
+ ">i2",
+ ) -> dtype[int16]: ...
+ "int32",
+ "i4",
+ "=i4",
+ "<i4",
+ ">i4",
+ ) -> dtype[int32]: ...
+ "int64",
+ "i8",
+ "=i8",
+ "<i8",
+ ">i8",
+ ) -> dtype[int64]: ...
+ # "int"/int resolve to int_, which is system dependent and as of
+ # now untyped. Long-term we'll do something fancier here.
+ dtype: Union[Type[int], Literal["int"]],
+ ) -> dtype: ...
+ "float16",
+ "f4",
+ "=f4",
+ "<f4",
+ ">f4",
+ "e",
+ "=e",
+ "<e",
+ ">e",
+ "half",
+ ) -> dtype[float16]: ...
+ "float32",
+ "f",
+ "=f",
+ "<f",
+ ">f",
+ "single",
+ ) -> dtype[float32]: ...
+ None,
+ Type[float],
+ "float64",
+ "f8",
+ "=f8",
+ "<f8",
+ ">f8",
+ "d",
+ "<d",
+ ">d",
+ "float",
+ "double",
+ "float_",
+ ) -> dtype[float64]: ...
+ "complex64",
+ "c8",
+ "=c8",
+ "<c8",
+ ">c8",
+ "F",
+ "=F",
+ "<F",
+ ">F",
+ ) -> dtype[complex64]: ...
+ Type[complex],
+ "complex128",
+ "c16",
+ "=c16",
+ "<c16",
+ ">c16",
+ "D",
+ "=D",
+ "<D",
+ ">D",
+ ) -> dtype[complex128]: ...
+ Type[bytes],
+ "S",
+ "=S",
+ "<S",
+ ">S",
+ "bytes",
+ "bytes_",
+ "bytes0",
+ ) -> dtype[bytes_]: ...
+ Type[str],
+ "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",
+ ) -> dtype[str_]: ...
+ # dtype of a dtype is the same dtype
+ dtype: dtype[_DTypeScalar],
+ # TODO: handle _SupportsDType better
+ dtype: _SupportsDType,
+ ) -> dtype[Any]: ...
+ # Handle strings that can't be expressed as literals; i.e. s1, s2, ...
+ dtype: str,
+ # Catchall overload
+ dtype: _VoidDTypeLike,
+ ) -> dtype[void]: ...
+ def __getitem__(self: dtype[void], key: List[str]) -> dtype[void]: ...
+ def __getitem__(self: dtype[void], key: Union[str, int]) -> dtype[Any]: ...
+ # NOTE: In the future 1-based multiplications will also yield `void` dtypes
+ def __mul__(self, value: Literal[0]) -> None: ... # type: ignore[misc]
+ def __mul__(self, value: Literal[1]) -> dtype[_DTypeScalar]: ...
+ def __mul__(self, value: int) -> dtype[void]: ...
+ # NOTE: `__rmul__` seems to be broken when used in combination with
+ # literals as of mypy 0.800. Set the return-type to `Any` for now.
+ def __rmul__(self, value: int) -> Any: ...
+ def __eq__(self, other: DTypeLike) -> bool: ...
+ def __ne__(self, other: DTypeLike) -> bool: ...
+ def __gt__(self, other: DTypeLike) -> bool: ...
+ def __ge__(self, other: DTypeLike) -> bool: ...
+ def __lt__(self, other: DTypeLike) -> bool: ...
+ def __le__(self, other: DTypeLike) -> bool: ...
+ def alignment(self) -> int: ...
+ def base(self) -> dtype: ...
+ def byteorder(self) -> str: ...
+ def char(self) -> str: ...
+ def descr(self) -> List[Union[Tuple[str, str], Tuple[str, str, _Shape]]]: ...
+ def fields(
+ self,
+ ) -> Optional[Mapping[str, Union[Tuple[dtype, int], Tuple[dtype, int, Any]]]]: ...
+ def flags(self) -> int: ...
+ def hasobject(self) -> bool: ...
+ def isbuiltin(self) -> int: ...
+ def isnative(self) -> bool: ...
+ def isalignedstruct(self) -> bool: ...
+ def itemsize(self) -> int: ...
+ def kind(self) -> str: ...
+ def metadata(self) -> Optional[Mapping[str, Any]]: ...
+ def name(self) -> str: ...
+ def names(self) -> Optional[Tuple[str, ...]]: ...
+ def num(self) -> int: ...
+ def shape(self) -> _Shape: ...
+ def ndim(self) -> int: ...
+ def subdtype(self) -> Optional[Tuple[dtype, _Shape]]: ...
+ def newbyteorder(self, __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
+ def str(self) -> builtins.str: ...
+ def type(self) -> Type[generic]: ...
+_DType = dtype # to avoid name conflicts with ndarray.dtype
+class _flagsobj:
+ aligned: bool
+ updateifcopy: bool
+ writeable: bool
+ writebackifcopy: bool
+ def behaved(self) -> bool: ...
+ def c_contiguous(self) -> bool: ...
+ def carray(self) -> bool: ...
+ def contiguous(self) -> bool: ...
+ def f_contiguous(self) -> bool: ...
+ def farray(self) -> bool: ...
+ def fnc(self) -> bool: ...
+ def forc(self) -> bool: ...
+ def fortran(self) -> bool: ...
+ def owndata(self) -> bool: ...
+ def __getitem__(self, key: str) -> bool: ...
+ def __setitem__(self, key: str, value: bool) -> None: ...
+_ArrayLikeInt = Union[
+ int,
+ integer,
+ Sequence[Union[int, integer]],
+ Sequence[Sequence[Any]], # TODO: wait for support for recursive types
+ ndarray
+]
+_FlatIterSelf = TypeVar("_FlatIterSelf", bound=flatiter)
+class flatiter(Generic[_ArraySelf]):
+ def base(self) -> _ArraySelf: ...
+ def coords(self) -> _Shape: ...
+ def index(self) -> int: ...
+ def copy(self) -> _ArraySelf: ...
+ def __iter__(self: _FlatIterSelf) -> _FlatIterSelf: ...
+ def __next__(self) -> generic: ...
+ def __len__(self) -> int: ...
+ def __getitem__(self, key: Union[int, integer]) -> generic: ...
+ 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[
+ ndarray,
+ Sequence[_IntLike],
+ Sequence[_BoolLike],
+_ArraySelf = TypeVar("_ArraySelf", bound=_ArrayOrScalarCommon)
+class _ArrayOrScalarCommon:
+ def T(self: _ArraySelf) -> _ArraySelf: ...
+ def data(self) -> memoryview: ...
+ def flags(self) -> _flagsobj: ...
+ def nbytes(self) -> int: ...
+ def __bool__(self) -> bool: ...
+ def __bytes__(self) -> bytes: ...
+ def __str__(self) -> str: ...
+ def __repr__(self) -> str: ...
+ def __copy__(self: _ArraySelf) -> _ArraySelf: ...
+ def __deepcopy__(self: _ArraySelf, __memo: Optional[dict] = ...) -> _ArraySelf: ...
+ 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 astype(
+ self: _ArraySelf,
+ dtype: DTypeLike,
+ order: _OrderKACF = ...,
+ casting: _Casting = ...,
+ subok: bool = ...,
+ 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 = ...
+ def ravel(self, order: _OrderKACF = ...) -> ndarray: ...
+ def reshape(
+ self, __shape: _ShapeLike, *, order: _OrderACF = ...
+ ) -> ndarray: ...
+ self, *shape: SupportsIndex, order: _OrderACF = ...
+ 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 = ...
+ ) -> None: ...
+ # generics and 0d arrays return builtin scalars
+ def tolist(self) -> Any: ...
+ def view(self, type: Type[_NdArraySubClass]) -> _NdArraySubClass: ...
+ def view(self: _ArraySelf, dtype: DTypeLike = ...) -> _ArraySelf: ...
+ def view(
+ self, dtype: DTypeLike, type: Type[_NdArraySubClass]
+ ) -> _NdArraySubClass: ...
+ # TODO: Add proper signatures
+ def __getitem__(self, key) -> Any: ...
+ def __array_interface__(self): ...
+ def __array_priority__(self): ...
+ 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
+ def all(
+ axis: None = ...,
+ out: None = ...,
+ keepdims: Literal[False] = ...,
+ ) -> bool_: ...
+ axis: Optional[_ShapeLike] = ...,
+ keepdims: bool = ...,
+ ) -> Any: ...
+ out: _NdArraySubClass = ...,
+ def any(
+ def argmax(
+ ) -> signedinteger[Any]: ...
+ axis: _ShapeLike = ...,
+ def argmin(
+ def argsort(
+ axis: Optional[SupportsIndex] = ...,
+ kind: Optional[_SortKind] = ...,
+ order: Union[None, str, Sequence[str]] = ...,
+ def choose(
+ choices: ArrayLike,
+ mode: _ModeKind = ...,
+ def clip(
+ min: ArrayLike = ...,
+ max: Optional[ArrayLike] = ...,
+ **kwargs: Any,
+ min: None = ...,
+ max: ArrayLike = ...,
+ def compress(
+ a: ArrayLike,
+ def conj(self: _ArraySelf) -> _ArraySelf: ...
+ def conjugate(self: _ArraySelf) -> _ArraySelf: ...
+ def cumprod(
+ dtype: DTypeLike = ...,
+ def cumsum(
+ def max(
+ initial: _NumberLike = ...,
+ where: _ArrayLikeBool = ...,
+ def mean(
+ def min(
+ def newbyteorder(
+ __new_order: _ByteOrder = ...,
+ def prod(
+ def ptp(
+ def repeat(
+ repeats: _ArrayLikeIntOrBool,
+ def round(
+ decimals: SupportsIndex = ...,
+ def std(
+ ddof: int = ...,
+ def sum(
+ def take(
+ indices: Union[_IntLike, _BoolLike],
+ indices: _ArrayLikeIntOrBool,
+ def var(
+_BufferType = Union[ndarray, bytes, bytearray, memoryview]
+_Casting = Literal["no", "equiv", "safe", "same_kind", "unsafe"]
+class ndarray(_ArrayOrScalarCommon, Iterable, Sized, Container):
+ def base(self) -> Optional[ndarray]: ...
+ def size(self) -> int: ...
+ def real(self: _ArraySelf) -> _ArraySelf: ...
+ @real.setter
+ def real(self, value: ArrayLike) -> None: ...
+ def imag(self: _ArraySelf) -> _ArraySelf: ...
+ @imag.setter
+ def imag(self, value: ArrayLike) -> None: ...
+ cls: Type[_ArraySelf],
+ shape: _ShapeLike,
+ buffer: _BufferType = ...,
+ offset: int = ...,
+ strides: _ShapeLike = ...,
+ def dtype(self) -> _DType: ...
+ def ctypes(self) -> _ctypes: ...
+ @shape.setter
+ def shape(self, value: _ShapeLike): ...
+ def strides(self) -> _Shape: ...
+ @strides.setter
+ def strides(self, value: _ShapeLike): ...
+ def byteswap(self: _ArraySelf, inplace: bool = ...) -> _ArraySelf: ...
+ def fill(self, value: Any) -> None: ...
+ def flat(self: _ArraySelf) -> flatiter[_ArraySelf]: ...
+ def item(self, *args: SupportsIndex) -> Any: ...
+ def item(self, __args: Tuple[SupportsIndex, ...]) -> Any: ...
+ def itemset(self, __value: Any) -> None: ...
+ def itemset(self, __item: _ShapeLike, __value: Any) -> None: ...
+ def resize(self, __new_shape: _ShapeLike, *, refcheck: bool = ...) -> None: ...
+ def resize(self, *new_shape: SupportsIndex, refcheck: bool = ...) -> None: ...
+ def setflags(
+ self, write: bool = ..., align: bool = ..., uic: bool = ...
+ def squeeze(
+ self: _ArraySelf, axis: Union[SupportsIndex, Tuple[SupportsIndex, ...]] = ...
+ def swapaxes(self: _ArraySelf, axis1: SupportsIndex, axis2: SupportsIndex) -> _ArraySelf: ...
+ def transpose(self: _ArraySelf, __axes: _ShapeLike) -> _ArraySelf: ...
+ def transpose(self: _ArraySelf, *axes: SupportsIndex) -> _ArraySelf: ...
+ def argpartition(
+ kth: _ArrayLikeIntOrBool,
+ kind: _PartitionKind = ...,
+ def diagonal(
+ offset: SupportsIndex = ...,
+ axis1: SupportsIndex = ...,
+ axis2: SupportsIndex = ...,
+ def dot(self, b: ArrayLike, out: None = ...) -> Any: ...
+ def dot(self, b: ArrayLike, out: _NdArraySubClass = ...) -> _NdArraySubClass: ...
+ # `nonzero()` is deprecated for 0d arrays/generics
+ def nonzero(self) -> Tuple[ndarray, ...]: ...
+ def partition(
+ axis: SupportsIndex = ...,
+ # `put` is technically available to `generic`,
+ # but is pointless as `generic`s are immutable
+ def put(
+ self, ind: _ArrayLikeIntOrBool, v: ArrayLike, mode: _ModeKind = ...
+ def searchsorted(
+ self, # >= 1D array
+ v: ArrayLike,
+ side: _SortSide = ...,
+ sorter: Optional[_ArrayLikeIntOrBool] = ..., # 1D int array
+ def setfield(
+ self, val: ArrayLike, dtype: DTypeLike, offset: SupportsIndex = ...
+ def sort(
+ def trace(
+ self, # >= 2D array
+ # 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: ...
+ def __setitem__(self, key, value): ...
+ def __iter__(self) -> Any: ...
+ def __contains__(self, key) -> bool: ...
+ def __matmul__(self, other: ArrayLike) -> Any: ...
+ # 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: ...
+ # `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: ...
+# NOTE: while `np.generic` is not technically an instance of `ABCMeta`,
+# the `@abstractmethod` decorator is herein used to (forcefully) deny
+# the creation of `np.generic` instances.
+# The `# type: ignore` comments are necessary to silence mypy errors regarding
+# the missing `ABCMeta` metaclass.
+# 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)
+class generic(_ArrayOrScalarCommon):
+ @abstractmethod
+ def __init__(self, *args: Any, **kwargs: Any) -> None: ...
+ def base(self) -> None: ...
+ def dtype(self: _ScalarType) -> _DType[_ScalarType]: ...
+ def ndim(self) -> Literal[0]: ...
+ def size(self) -> Literal[1]: ...
+ def shape(self) -> Tuple[()]: ...
+ def strides(self) -> Tuple[()]: ...
+ def byteswap(self: _ScalarType, inplace: Literal[False] = ...) -> _ScalarType: ...
+ def flat(self) -> flatiter[ndarray]: ...
+ def item(
+ self: _ScalarType,
+ __args: Union[Literal[0], Tuple[()], Tuple[Literal[0]]] = ...,
+ self: _ScalarType, axis: Union[Literal[0], Tuple[()]] = ...
+ ) -> _ScalarType: ...
+ def transpose(self: _ScalarType, __axes: Tuple[()] = ...) -> _ScalarType: ...
+class number(generic, Generic[_NBit_co]): # type: ignore
+ def __neg__(self: _ArraySelf) -> _ArraySelf: ...
+ def __pos__(self: _ArraySelf) -> _ArraySelf: ...
+ def __abs__(self: _ArraySelf) -> _ArraySelf: ...
+ # Ensure that objects annotated as `number` support arithmetic operations
+ __add__: _NumberOp
+ __radd__: _NumberOp
+ __sub__: _NumberOp
+ __rsub__: _NumberOp
+ __mul__: _NumberOp
+ __rmul__: _NumberOp
+ __floordiv__: _NumberOp
+ __rfloordiv__: _NumberOp
+ __pow__: _NumberOp
+ __rpow__: _NumberOp
+ __truediv__: _NumberOp
+ __rtruediv__: _NumberOp
+class bool_(generic):
+ def __init__(self, __value: object = ...) -> None: ...
+ __add__: _BoolOp[bool_]
+ __radd__: _BoolOp[bool_]
+ __sub__: _BoolSub
+ __rsub__: _BoolSub
+ __mul__: _BoolOp[bool_]
+ __rmul__: _BoolOp[bool_]
+ __floordiv__: _BoolOp[int8]
+ __rfloordiv__: _BoolOp[int8]
+ __pow__: _BoolOp[int8]
+ __rpow__: _BoolOp[int8]
+ __truediv__: _BoolTrueDiv
+ __rtruediv__: _BoolTrueDiv
+ def __invert__(self) -> bool_: ...
+ __lshift__: _BoolBitOp[int8]
+ __rlshift__: _BoolBitOp[int8]
+ __rshift__: _BoolBitOp[int8]
+ __rrshift__: _BoolBitOp[int8]
+ __and__: _BoolBitOp[bool_]
+ __rand__: _BoolBitOp[bool_]
+ __xor__: _BoolBitOp[bool_]
+ __rxor__: _BoolBitOp[bool_]
+ __or__: _BoolBitOp[bool_]
+ __ror__: _BoolBitOp[bool_]
+ __mod__: _BoolMod
+ __rmod__: _BoolMod
+ __divmod__: _BoolDivMod
+ __rdivmod__: _BoolDivMod
+class object_(generic):
+# The `datetime64` constructors requires an object with the three attributes below,
+# and thus supports datetime duck typing
+class _DatetimeScalar(Protocol):
+ def day(self) -> int: ...
+ def month(self) -> int: ...
+ def year(self) -> int: ...
+class datetime64(generic):
+ def __init__(
+ __value: Union[None, datetime64, _CharLike, _DatetimeScalar] = ...,
+ __format: Union[_CharLike, Tuple[_CharLike, _IntLike]] = ...,
+ __value: int,
+ __format: Union[_CharLike, Tuple[_CharLike, _IntLike]]
+ def __add__(self, other: Union[timedelta64, _IntLike, _BoolLike]) -> datetime64: ...
+ def __radd__(self, other: Union[timedelta64, _IntLike, _BoolLike]) -> datetime64: ...
+ def __sub__(self, other: datetime64) -> timedelta64: ...
+ def __sub__(self, other: Union[timedelta64, _IntLike, _BoolLike]) -> datetime64: ...
+ def __rsub__(self, other: datetime64) -> timedelta64: ...
+# Support for `__index__` was added in python 3.8 (bpo-20092)
+ _IntValue = Union[SupportsInt, _CharLike, SupportsIndex]
+ _FloatValue = Union[None, _CharLike, SupportsFloat, SupportsIndex]
+ _ComplexValue = Union[None, _CharLike, SupportsFloat, SupportsComplex, SupportsIndex]
+ _IntValue = Union[SupportsInt, _CharLike]
+ _FloatValue = Union[None, _CharLike, SupportsFloat]
+ _ComplexValue = Union[None, _CharLike, SupportsFloat, SupportsComplex]
+class integer(number[_NBit_co]): # type: ignore
+ # NOTE: `__index__` is technically defined in the bottom-most
+ # sub-classes (`int64`, `uint32`, etc)
+ __truediv__: _IntTrueDiv[_NBit_co]
+ __rtruediv__: _IntTrueDiv[_NBit_co]
+ def __mod__(self, value: Union[_IntLike, integer]) -> integer: ...
+ def __rmod__(self, value: Union[_IntLike, integer]) -> 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 __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]
+int8 = signedinteger[_8Bit]
+int16 = signedinteger[_16Bit]
+int32 = signedinteger[_32Bit]
+int64 = signedinteger[_64Bit]
+class timedelta64(generic):
+ __value: Union[None, int, _CharLike, dt.timedelta, timedelta64] = ...,
+ 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: ...
+ __truediv__: _TD64Div[float64]
+ __floordiv__: _TD64Div[int64]
+ def __rtruediv__(self, other: timedelta64) -> float64: ...
+ def __rfloordiv__(self, other: timedelta64) -> int64: ...
+ def __mod__(self, other: timedelta64) -> timedelta64: ...
+ def __rmod__(self, other: timedelta64) -> timedelta64: ...
+ def __divmod__(self, other: timedelta64) -> Tuple[int64, timedelta64]: ...
+ def __rdivmod__(self, other: timedelta64) -> Tuple[int64, timedelta64]: ...
+class unsignedinteger(integer[_NBit_co]):
+ # NOTE: `uint64 + signedinteger -> float64`
+ __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]
+uint8 = unsignedinteger[_8Bit]
+uint16 = unsignedinteger[_16Bit]
+uint32 = unsignedinteger[_32Bit]
+uint64 = unsignedinteger[_64Bit]
+class inexact(number[_NBit_co]): ... # type: ignore
+_IntType = TypeVar("_IntType", bound=integer)
+_FloatType = TypeVar('_FloatType', bound=floating)
+class floating(inexact[_NBit_co]):
+ 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]
+float16 = floating[_16Bit]
+float32 = floating[_32Bit]
+float64 = floating[_64Bit]
+# 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]):
+ def __init__(self, __value: _ComplexValue = ...) -> None: ...
+ def real(self) -> floating[_NBit_co]: ... # type: ignore[override]
+ 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]
+complex64 = complexfloating[_32Bit, _32Bit]
+complex128 = complexfloating[_64Bit, _64Bit]
+class flexible(generic): ... # type: ignore
+class void(flexible):
+ def __init__(self, __value: Union[_IntLike, _BoolLike, bytes]): ...
+ self, val: ArrayLike, dtype: DTypeLike, offset: int = ...
+class character(flexible): # type: ignore
+# NOTE: Most `np.bytes_` / `np.str_` methods return their
+# builtin `bytes` / `str` counterpart
+class bytes_(character, bytes):
+ self, __value: str, encoding: str = ..., errors: str = ...
+class str_(character, str):
+ self, __value: bytes, encoding: str = ..., errors: 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,
+ *,
+ ndmin: int = ...,
+ like: ArrayLike = ...,
+) -> ndarray: ...
+def zeros(
+ order: _OrderCF = ...,
+def empty(
+def broadcast_shapes(*args: _ShapeLike) -> _Shape: ...
+# Constants
+Inf: Final[float]
+Infinity: Final[float]
+NAN: Final[float]
+NINF: Final[float]
+NZERO: Final[float]
+NaN: Final[float]
+PINF: Final[float]
+PZERO: Final[float]
+e: Final[float]
+euler_gamma: Final[float]
+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]
+little_endian: Final[bool]
+True_: Final[bool_]
+False_: Final[bool_]
+UFUNC_PYVALS_NAME: Final[str]
+class ufunc:
+ def __name__(self) -> str: ...
+ def __call__(
+ *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 = ...,
+ 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]] = ...,
+ def nin(self) -> int: ...
+ def nout(self) -> int: ...
+ def nargs(self) -> int: ...
+ def ntypes(self) -> int: ...
+ def types(self) -> List[str]: ...
+ # Broad return type because it has to encompass things like
+ # >>> np.logical_and.identity is True
+ # True
+ # >>> np.add.identity is 0
+ # >>> np.sin.identity is None
+ # and any user-defined ufuncs.
+ def identity(self) -> Any: ...
+ # This is None for ufuncs and a string for gufuncs.
+ def signature(self) -> Optional[str]: ...
+ # The next four methods will always exist, but they will just
+ # 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.
+ def reduce(self) -> Any: ...
+ def accumulate(self) -> Any: ...
+ def reduceat(self) -> Any: ...
+ def outer(self) -> Any: ...
+ # Similarly at won't be defined for ufuncs that return multiple
+ # outputs, so we can't type it very precisely.
+ 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
+abs = absolute
+# Warnings
+class ModuleDeprecationWarning(DeprecationWarning): ...
+class VisibleDeprecationWarning(UserWarning): ...
+class ComplexWarning(RuntimeWarning): ...
+class RankWarning(UserWarning): ...
+# Errors
+class TooHardError(RuntimeError): ...
+class AxisError(ValueError, IndexError):
+ self, axis: int, ndim: Optional[int] = ..., msg_prefix: Optional[str] = ...
+_CallType = TypeVar("_CallType", bound=Union[_ErrFunc, _SupportsWrite])
+class errstate(Generic[_CallType], ContextDecorator):
+ call: _CallType
+ kwargs: _ErrDictOptional
+ # Expand `**kwargs` into explicit keyword-only arguments
+ call: _CallType = ...,
+ all: Optional[_ErrKind] = ...,
+ divide: Optional[_ErrKind] = ...,
+ over: Optional[_ErrKind] = ...,
+ under: Optional[_ErrKind] = ...,
+ invalid: Optional[_ErrKind] = ...,
+ def __enter__(self) -> None: ...
+ def __exit__(
+ __exc_type: Optional[Type[BaseException]],
+ __exc_value: Optional[BaseException],
+ __traceback: Optional[TracebackType],
@@ -0,0 +1,32 @@
+'''
+Helper to preload windows dlls to prevent dll not found errors.
+Once a DLL is preloaded, its namespace is made available to any
+subsequent DLL. This file originated in the numpy-wheels repo,
+and is created as part of the scripts that build the wheel.
+import glob
+if os.name == 'nt':
+ # convention for storing / loading the DLL from
+ # numpy/.libs/, if present
+ from ctypes import WinDLL
+ basedir = os.path.dirname(__file__)
+ except:
+ libs_dir = os.path.abspath(os.path.join(basedir, '.libs'))
+ DLL_filenames = []
+ if os.path.isdir(libs_dir):
+ for filename in glob.glob(os.path.join(libs_dir,
+ '*openblas*dll')):
+ # NOTE: would it change behavior to load ALL
+ # DLLs at this path vs. the name restriction?
+ WinDLL(os.path.abspath(filename))
+ DLL_filenames.append(filename)
+ if len(DLL_filenames) > 1:
+ import warnings
+ warnings.warn("loaded more than 1 DLL from .libs:"
+ "\n%s" % "\n".join(DLL_filenames),
+ stacklevel=1)
@@ -0,0 +1,79 @@
+Module defining global singleton classes.
+This module raises a RuntimeError if an attempt to reload it is made. In that
+way the identities of the classes defined here are fixed and will remain so
+even if numpy itself is reloaded. In particular, a function like the following
+will still work correctly after numpy is reloaded::
+ def foo(arg=np._NoValue):
+ if arg is np._NoValue:
+ ...
+That was not the case when the singleton classes were defined in the numpy
+``__init__.py`` file. See gh-7844 for a discussion of the reload problem that
+motivated this module.
+__ALL__ = [
+ 'ModuleDeprecationWarning', 'VisibleDeprecationWarning', '_NoValue'
+# Disallow reloading this module so as to preserve the identities of the
+# classes defined here.
+if '_is_loaded' in globals():
+ raise RuntimeError('Reloading numpy._globals is not allowed')
+_is_loaded = True
+class ModuleDeprecationWarning(DeprecationWarning):
+ """Module deprecation warning.
+ The nose tester turns ordinary Deprecation warnings into test failures.
+ That makes it hard to deprecate whole modules, because they get
+ imported by default. So this is a special Deprecation warning that the
+ nose tester will let pass without making tests fail.
+ModuleDeprecationWarning.__module__ = 'numpy'
+class VisibleDeprecationWarning(UserWarning):
+ """Visible deprecation warning.
+ By default, python will not show deprecation warnings, so this class
+ can be used when a very visible warning is helpful, for example because
+ the usage is most likely a user bug.
+VisibleDeprecationWarning.__module__ = 'numpy'
+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.
+ __instance = None
+ def __new__(cls):
+ # ensure that only one instance exists
+ if not cls.__instance:
+ cls.__instance = super(_NoValueType, cls).__new__(cls)
+ return cls.__instance
+ # needed for python 2 to preserve identity through a pickle
+ def __reduce__(self):
+ return (self.__class__, ())
+ def __repr__(self):
+ return "<no value>"
+_NoValue = _NoValueType()
@@ -0,0 +1,213 @@
+Pytest test running.
+This module implements the ``test()`` function for NumPy modules. The usual
+boiler plate for doing that is to put the following in the module
+``__init__.py`` file::
+Warnings filtering and other runtime settings should be dealt with in the
+``pytest.ini`` file in the numpy repo root. The behavior of the test depends on
+whether or not that file is found as follows:
+* ``pytest.ini`` is present (develop mode)
+ All warnings except those explicitly filtered out are raised as error.
+* ``pytest.ini`` is absent (release mode)
+ DeprecationWarnings and PendingDeprecationWarnings are ignored, other
+ warnings are passed through.
+In practice, tests run from the numpy repo are run in develop mode. That
+includes the standard ``python runtests.py`` invocation.
+This module is imported by every numpy subpackage, so lies at the top level to
+simplify circular import issues. For the same reason, it contains no numpy
+imports at module scope, instead importing numpy within function calls.
+__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"
+ enabled_features = ' '.join(__cpu_baseline__)
+ for feature in __cpu_dispatch__:
+ if __cpu_features__[feature]:
+ enabled_features += " %s*" % feature
+ enabled_features += " %s?" % feature
+ print("NumPy CPU features:", enabled_features)
+class PytestTester:
+ Pytest test runner.
+ A test function is typically added to a package's __init__.py like so::
+ test = PytestTester(__name__).test
+ Calling this test function finds and runs all tests associated with the
+ module and all its sub-modules.
+ Attributes
+ module_name : str
+ Full path to the package to test.
+ module_name : module name
+ The name of the module to test.
+ Unlike the previous ``nose``-based implementation, this class is not
+ publicly exposed as it performs some ``numpy``-specific warning
+ suppression.
+ def __init__(self, module_name):
+ self.module_name = module_name
+ def __call__(self, label='fast', verbose=1, extra_argv=None,
+ doctests=False, coverage=False, durations=-1, tests=None):
+ Run tests for module using pytest.
+ label : {'fast', 'full'}, optional
+ Identifies the tests to run. When set to 'fast', tests decorated
+ with `pytest.mark.slow` are skipped, when 'full', the slow marker
+ is ignored.
+ verbose : int, optional
+ Verbosity value for test outputs, in the range 1-3. Default is 1.
+ extra_argv : list, optional
+ List with any extra arguments to pass to pytests.
+ doctests : bool, optional
+ .. note:: Not supported
+ coverage : bool, optional
+ If True, report coverage of NumPy code. Default is False.
+ Requires installation of (pip) pytest-cov.
+ durations : int, optional
+ If < 0, do nothing, If 0, report time of all tests, if > 0,
+ report the time of the slowest `timer` tests. Default is -1.
+ tests : test or list of tests
+ Tests to be executed with pytest '--pyargs'
+ result : bool
+ Return True on success, false otherwise.
+ Each NumPy module exposes `test` in its namespace to run all tests for
+ it. For example, to run all tests for numpy.lib:
+ >>> np.lib.test() #doctest: +SKIP
+ >>> result = np.lib.test() #doctest: +SKIP
+ 1023 passed, 2 skipped, 6 deselected, 1 xfailed in 10.39 seconds
+ >>> result
+ True
+ import pytest
+ module = sys.modules[self.module_name]
+ module_path = os.path.abspath(module.__path__[0])
+ # setup the pytest arguments
+ pytest_args = ["-l"]
+ # offset verbosity. The "-q" cancels a "-v".
+ pytest_args += ["-q"]
+ # Filter out distutils cpu warnings (could be localized to
+ # distutils tests). ASV has problems with top level import,
+ # so fetch module for suppression here.
+ with warnings.catch_warnings():
+ warnings.simplefilter("always")
+ from numpy.distutils import cpuinfo
+ # Filter out annoying import messages. Want these in both develop and
+ # release mode.
+ pytest_args += [
+ "-W ignore:Not importing directory",
+ "-W ignore:numpy.dtype size changed",
+ "-W ignore:numpy.ufunc size changed",
+ "-W ignore::UserWarning:cpuinfo",
+ # When testing matrices, ignore their PendingDeprecationWarnings
+ "-W ignore:the matrix subclass is not",
+ "-W ignore:Importing from numpy.matlib is",
+ if doctests:
+ raise ValueError("Doctests not supported")
+ if extra_argv:
+ pytest_args += list(extra_argv)
+ if verbose > 1:
+ pytest_args += ["-" + "v"*(verbose - 1)]
+ if coverage:
+ pytest_args += ["--cov=" + module_path]
+ if label == "fast":
+ # not importing at the top level to avoid circular import of module
+ from numpy.testing import IS_PYPY
+ if IS_PYPY:
+ pytest_args += ["-m", "not slow and not slow_pypy"]
+ pytest_args += ["-m", "not slow"]
+ elif label != "full":
+ pytest_args += ["-m", label]
+ if durations >= 0:
+ pytest_args += ["--durations=%s" % durations]
+ if tests is None:
+ tests = [self.module_name]
+ pytest_args += ["--pyargs"] + list(tests)
+ # run tests.
+ _show_numpy_info()
+ code = pytest.main(pytest_args)
+ except SystemExit as exc:
+ code = exc.code
+ return code == 0
@@ -0,0 +1,56 @@
+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
+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
+splitlines: Any
+startswith: Any
+strip: Any
+swapcase: Any
+title: Any
+translate: Any
+upper: Any
+zfill: Any
+isnumeric: Any
+isdecimal: Any
+array: Any
+asarray: Any
@@ -0,0 +1,18 @@
+Compatibility module.
+This module contains duplicated code from Python itself or 3rd party
+extensions, which may be included for the following reasons:
+ * compatibility
+ * we may only need a small subset of the copied library/module
+from . import _inspect
+from . import py3k
+from ._inspect import getargspec, formatargspec
+from .py3k import *
+__all__ = []
+__all__.extend(_inspect.__all__)
+__all__.extend(py3k.__all__)
@@ -0,0 +1,191 @@
+"""Subset of inspect module from upstream python
+We use this instead of upstream because upstream inspect is slow to import, and
+significantly contributes to numpy import times. Importing this copy has almost
+no overhead.
+import types
+__all__ = ['getargspec', 'formatargspec']
+# ----------------------------------------------------------- type-checking
+def ismethod(object):
+ """Return true if the object is an instance method.
+ Instance method objects provide these attributes:
+ __doc__ documentation string
+ __name__ name with which this method was defined
+ im_class class object in which this method belongs
+ im_func function object containing implementation of method
+ im_self instance to which this method is bound, or None
+ return isinstance(object, types.MethodType)
+def isfunction(object):
+ """Return true if the object is a user-defined function.
+ Function objects provide these attributes:
+ __name__ name with which this function was defined
+ func_code code object containing compiled function bytecode
+ func_defaults tuple of any default values for arguments
+ func_doc (same as __doc__)
+ func_globals global namespace in which this function was defined
+ func_name (same as __name__)
+ return isinstance(object, types.FunctionType)
+def iscode(object):
+ """Return true if the object is a code object.
+ Code objects provide these attributes:
+ co_argcount number of arguments (not including * or ** args)
+ co_code string of raw compiled bytecode
+ co_consts tuple of constants used in the bytecode
+ co_filename name of file in which this code object was created
+ co_firstlineno number of first line in Python source code
+ co_flags bitmap: 1=optimized | 2=newlocals | 4=*arg | 8=**arg
+ co_lnotab encoded mapping of line numbers to bytecode indices
+ co_name name with which this code object was defined
+ co_names tuple of names of local variables
+ co_nlocals number of local variables
+ co_stacksize virtual machine stack space required
+ co_varnames tuple of names of arguments and local variables
+ return isinstance(object, types.CodeType)
+# ------------------------------------------------ argument list extraction
+# These constants are from Python's compile.h.
+CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS = 1, 2, 4, 8
+def getargs(co):
+ """Get information about the arguments accepted by a code object.
+ Three things are returned: (args, varargs, varkw), where 'args' is
+ a list of argument names (possibly containing nested lists), and
+ 'varargs' and 'varkw' are the names of the * and ** arguments or None.
+ if not iscode(co):
+ raise TypeError('arg is not a code object')
+ nargs = co.co_argcount
+ names = co.co_varnames
+ args = list(names[:nargs])
+ # The following acrobatics are for anonymous (tuple) arguments.
+ # Which we do not need to support, so remove to avoid importing
+ # the dis module.
+ for i in range(nargs):
+ if args[i][:1] in ['', '.']:
+ raise TypeError("tuple function arguments are not supported")
+ varargs = None
+ if co.co_flags & CO_VARARGS:
+ varargs = co.co_varnames[nargs]
+ nargs = nargs + 1
+ varkw = None
+ if co.co_flags & CO_VARKEYWORDS:
+ varkw = co.co_varnames[nargs]
+ return args, varargs, varkw
+def getargspec(func):
+ """Get the names and default values of a function's arguments.
+ A tuple of four things is returned: (args, varargs, varkw, defaults).
+ 'args' is a list of the argument names (it may contain nested lists).
+ 'defaults' is an n-tuple of the default values of the last n arguments.
+ if ismethod(func):
+ func = func.__func__
+ if not isfunction(func):
+ raise TypeError('arg is not a Python function')
+ args, varargs, varkw = getargs(func.__code__)
+ return args, varargs, varkw, func.__defaults__
+def getargvalues(frame):
+ """Get information about arguments passed into a particular frame.
+ A tuple of four things is returned: (args, varargs, varkw, locals).
+ 'locals' is the locals dictionary of the given frame.
+ args, varargs, varkw = getargs(frame.f_code)
+ return args, varargs, varkw, frame.f_locals
+def joinseq(seq):
+ if len(seq) == 1:
+ return '(' + seq[0] + ',)'
+ return '(' + ', '.join(seq) + ')'
+def strseq(object, convert, join=joinseq):
+ """Recursively walk a sequence, stringifying each element.
+ if type(object) in [list, tuple]:
+ return join([strseq(_o, convert, join) for _o in object])
+ return convert(object)
+def formatargspec(args, varargs=None, varkw=None, defaults=None,
+ formatarg=str,
+ formatvarargs=lambda name: '*' + name,
+ formatvarkw=lambda name: '**' + name,
+ formatvalue=lambda value: '=' + repr(value),
+ join=joinseq):
+ """Format an argument spec from the 4 values returned by getargspec.
+ The first four arguments are (args, varargs, varkw, defaults). The
+ other four arguments are the corresponding optional formatting functions
+ that are called to turn names and values into strings. The ninth
+ argument is an optional function to format the sequence of arguments.
+ specs = []
+ if defaults:
+ firstdefault = len(args) - len(defaults)
+ for i in range(len(args)):
+ spec = strseq(args[i], formatarg, join)
+ if defaults and i >= firstdefault:
+ spec = spec + formatvalue(defaults[i - firstdefault])
+ specs.append(spec)
+ if varargs is not None:
+ specs.append(formatvarargs(varargs))
+ if varkw is not None:
+ specs.append(formatvarkw(varkw))
+ return '(' + ', '.join(specs) + ')'
+def formatargvalues(args, varargs, varkw, locals,
+ """Format an argument spec from the 4 values returned by getargvalues.
+ The first four arguments are (args, varargs, varkw, locals). The
+ next four arguments are the corresponding optional formatting functions
+ def convert(name, locals=locals,
+ formatarg=formatarg, formatvalue=formatvalue):
+ return formatarg(name) + formatvalue(locals[name])
+ specs = [strseq(arg, convert, join) for arg in args]
+ if varargs:
+ specs.append(formatvarargs(varargs) + formatvalue(locals[varargs]))
+ if varkw:
+ specs.append(formatvarkw(varkw) + formatvalue(locals[varkw]))
@@ -0,0 +1,136 @@
+Python 3.X compatibility tools.
+While this file was originally intended for Python 2 -> 3 transition,
+it is now used to create a compatibility layer between different
+minor versions of Python 3.
+While the active version of numpy may not support a given version of python, we
+allow downstream libraries to continue to use these shims for forward
+compatibility with numpy while they transition their code to newer versions of
+Python.
+__all__ = ['bytes', 'asbytes', 'isfileobj', 'getexception', 'strchar',
+ 'unicode', 'asunicode', 'asbytes_nested', 'asunicode_nested',
+ 'asstr', 'open_latin1', 'long', 'basestring', 'sixu',
+ 'integer_types', 'is_pathlib_path', 'npy_load_module', 'Path',
+ 'pickle', 'contextlib_nullcontext', 'os_fspath', 'os_PathLike']
+from pathlib import Path
+import io
+import abc
+from abc import ABC as abc_ABC
+ import pickle5 as pickle
+except ImportError:
+ import pickle
+long = int
+integer_types = (int,)
+basestring = str
+unicode = str
+bytes = bytes
+def asunicode(s):
+ if isinstance(s, bytes):
+ return s.decode('latin1')
+ return str(s)
+def asbytes(s):
+ return s
+ return str(s).encode('latin1')
+def asstr(s):
+def isfileobj(f):
+ return isinstance(f, (io.FileIO, io.BufferedReader, io.BufferedWriter))
+def open_latin1(filename, mode='r'):
+ return open(filename, mode=mode, encoding='iso-8859-1')
+def sixu(s):
+strchar = 'U'
+def getexception():
+ return sys.exc_info()[1]
+def asbytes_nested(x):
+ if hasattr(x, '__iter__') and not isinstance(x, (bytes, unicode)):
+ return [asbytes_nested(y) for y in x]
+ return asbytes(x)
+def asunicode_nested(x):
+ return [asunicode_nested(y) for y in x]
+ return asunicode(x)
+def is_pathlib_path(obj):
+ Check whether obj is a `pathlib.Path` object.
+ Prefer using ``isinstance(obj, os.PathLike)`` instead of this function.
+ return isinstance(obj, Path)
+# from Python 3.7
+class contextlib_nullcontext:
+ """Context manager that does no additional processing.
+ Used as a stand-in for a normal context manager, when a particular
+ block of code is only sometimes used with a normal context manager:
+ cm = optional_cm if condition else nullcontext()
+ with cm:
+ # Perform operation, using optional_cm if condition is True
+ def __init__(self, enter_result=None):
+ self.enter_result = enter_result
+ def __enter__(self):
+ return self.enter_result
+ def __exit__(self, *excinfo):
+def npy_load_module(name, fn, info=None):
+ Load a module.
+ .. versionadded:: 1.11.2
+ name : str
+ Full module name.
+ fn : str
+ Path to module file.
+ info : tuple, optional
+ Only here for backward compatibility with Python 2.*.
+ mod : module
+ # Explicitly lazy import this to avoid paying the cost
+ # of importing importlib at startup
+ from importlib.machinery import SourceFileLoader
+ return SourceFileLoader(name, fn).load_module()
+os_fspath = os.fspath
+os_PathLike = os.PathLike
@@ -0,0 +1,10 @@
+def configuration(parent_package='',top_path=None):
+ from numpy.distutils.misc_util import Configuration
+ config = Configuration('compat', parent_package, top_path)
+ config.add_subpackage('tests')
+ return config
+if __name__ == '__main__':
+ from numpy.distutils.core import setup
+ setup(configuration=configuration)
@@ -0,0 +1,19 @@
+from os.path import join
+from numpy.compat import isfileobj
+from numpy.testing import assert_
+from numpy.testing import tempdir
+def test_isfileobj():
+ with tempdir(prefix="numpy_test_compat_") as folder:
+ filename = join(folder, 'a.bin')
+ with open(filename, 'wb') as f:
+ assert_(isfileobj(f))
+ with open(filename, 'ab') as f:
+ with open(filename, 'rb') as f:
@@ -0,0 +1,119 @@
+Pytest configuration and fixtures for the Numpy test suite.
+import tempfile
+import hypothesis
+import pytest
+import numpy
+from numpy.core._multiarray_tests import get_fpu_mode
+_old_fpu_mode = None
+_collect_results = {}
+# Use a known and persistent tmpdir for hypothesis' caches, which
+# can be automatically cleared by the OS or user.
+hypothesis.configuration.set_hypothesis_home_dir(
+ os.path.join(tempfile.gettempdir(), ".hypothesis")
+# We register two custom profiles for Numpy - for details see
+# https://hypothesis.readthedocs.io/en/latest/settings.html
+# The first is designed for our own CI runs; the latter also
+# forces determinism and is designed for use via np.test()
+hypothesis.settings.register_profile(
+ name="numpy-profile", deadline=None, print_blob=True,
+ name="np.test() profile",
+ deadline=None, print_blob=True, database=None, derandomize=True,
+ suppress_health_check=hypothesis.HealthCheck.all(),
+# Note that the default profile is chosen based on the presence
+# of pytest.ini, but can be overriden by passing the
+# --hypothesis-profile=NAME argument to pytest.
+_pytest_ini = os.path.join(os.path.dirname(__file__), "..", "pytest.ini")
+hypothesis.settings.load_profile(
+ "numpy-profile" if os.path.isfile(_pytest_ini) else "np.test() profile"
+def pytest_configure(config):
+ config.addinivalue_line("markers",
+ "valgrind_error: Tests that are known to error under valgrind.")
+ "leaks_references: Tests that are known to leak references.")
+ "slow: Tests that are very slow.")
+ "slow_pypy: Tests that are very slow on pypy.")
+def pytest_addoption(parser):
+ parser.addoption("--available-memory", action="store", default=None,
+ help=("Set amount of memory available for running the "
+ "test suite. This can result to tests requiring "
+ "especially large amounts of memory to be skipped. "
+ "Equivalent to setting environment variable "
+ "NPY_AVAILABLE_MEM. Default: determined"
+ "automatically."))
+def pytest_sessionstart(session):
+ available_mem = session.config.getoption('available_memory')
+ if available_mem is not None:
+ os.environ['NPY_AVAILABLE_MEM'] = available_mem
+#FIXME when yield tests are gone.
+@pytest.hookimpl()
+def pytest_itemcollected(item):
+ Check FPU precision mode was not changed during test collection.
+ The clumsy way we do it here is mainly necessary because numpy
+ still uses yield tests, which can execute code at test collection
+ time.
+ global _old_fpu_mode
+ mode = get_fpu_mode()
+ if _old_fpu_mode is None:
+ _old_fpu_mode = mode
+ elif mode != _old_fpu_mode:
+ _collect_results[item] = (_old_fpu_mode, mode)
+@pytest.fixture(scope="function", autouse=True)
+def check_fpu_mode(request):
+ Check FPU precision mode was not changed during the test.
+ old_mode = get_fpu_mode()
+ yield
+ new_mode = get_fpu_mode()
+ if old_mode != new_mode:
+ raise AssertionError("FPU precision mode changed from {0:#x} to {1:#x}"
+ " during the test".format(old_mode, new_mode))
+ collect_result = _collect_results.get(request.node)
+ if collect_result is not None:
+ old_mode, new_mode = collect_result
+ " when collecting the test".format(old_mode,
+ new_mode))
+@pytest.fixture(autouse=True)
+def add_np(doctest_namespace):
+ doctest_namespace['np'] = numpy
+def env_setup(monkeypatch):
+ monkeypatch.setenv('PYTHONHASHSEED', '0')
@@ -0,0 +1,166 @@
+Contains the core of NumPy: ndarray, ufuncs, dtypes, etc.
+Please note that this module is private. All functions and objects
+are available in the main ``numpy`` namespace - use that instead.
+from numpy.version import version as __version__
+# disables OpenBLAS affinity setting of the main thread that limits
+# python threads or processes to one core
+env_added = []
+for envkey in ['OPENBLAS_MAIN_FREE', 'GOTOBLAS_MAIN_FREE']:
+ if envkey not in os.environ:
+ os.environ[envkey] = '1'
+ env_added.append(envkey)
+ from . import multiarray
+except ImportError as exc:
+ msg = """
+IMPORTANT: PLEASE READ THIS FOR ADVICE ON HOW TO SOLVE THIS ISSUE!
+Importing the numpy C-extensions failed. This error can happen for
+many reasons, often due to issues with your setup or how NumPy was
+installed.
+We have compiled some common reasons and troubleshooting tips at:
+ https://numpy.org/devdocs/user/troubleshooting-importerror.html
+Please note and check the following:
+ * The Python version is: Python%d.%d from "%s"
+ * The NumPy version is: "%s"
+and make sure that they are the versions you expect.
+Please carefully study the documentation linked above for further help.
+Original error was: %s
+""" % (sys.version_info[0], sys.version_info[1], sys.executable,
+ __version__, exc)
+ raise ImportError(msg)
+finally:
+ for envkey in env_added:
+ del os.environ[envkey]
+del envkey
+del env_added
+del os
+from . import umath
+# Check that multiarray,umath are pure python modules wrapping
+# _multiarray_umath and not either of the old c-extension modules
+if not (hasattr(multiarray, '_multiarray_umath') and
+ hasattr(umath, '_multiarray_umath')):
+ path = sys.modules['numpy'].__path__
+ msg = ("Something is wrong with the numpy installation. "
+ "While importing we detected an older version of "
+ "numpy in {}. One method of fixing this is to repeatedly uninstall "
+ "numpy until none is found, then reinstall this version.")
+ raise ImportError(msg.format(path))
+from . import numerictypes as nt
+multiarray.set_typeDict(nt.sctypeDict)
+from . import numeric
+from .numeric import *
+from . import fromnumeric
+from .fromnumeric import *
+from . import defchararray as char
+from . import records as rec
+from .records import *
+from .memmap import *
+from .defchararray import chararray
+from . import function_base
+from .function_base import *
+from . import machar
+from .machar import *
+from . import getlimits
+from .getlimits import *
+from . import shape_base
+from .shape_base import *
+from . import einsumfunc
+from .einsumfunc import *
+del nt
+from .fromnumeric import amax as max, amin as min, round_ as round
+from .numeric import absolute as abs
+# do this after everything else, to minimize the chance of this misleadingly
+# appearing in an import-time traceback
+from . import _add_newdocs
+from . import _add_newdocs_scalars
+# add these for module-freeze analysis (like PyInstaller)
+from . import _dtype_ctypes
+from . import _internal
+from . import _dtype
+from . import _methods
+__all__ = ['char', 'rec', 'memmap']
+__all__ += numeric.__all__
+__all__ += fromnumeric.__all__
+__all__ += rec.__all__
+__all__ += ['chararray']
+__all__ += function_base.__all__
+__all__ += machar.__all__
+__all__ += getlimits.__all__
+__all__ += shape_base.__all__
+__all__ += einsumfunc.__all__
+# We used to use `np.core._ufunc_reconstruct` to unpickle. This is unnecessary,
+# but old pickles saved before 1.20 will be using it, and there is no reason
+# to break loading them.
+def _ufunc_reconstruct(module, name):
+ # The `fromlist` kwarg is required to ensure that `mod` points to the
+ # inner-most module rather than the parent package when module name is
+ # nested. This makes it possible to pickle non-toplevel ufuncs such as
+ # scipy.special.expit for instance.
+ 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
+ # make sense to add a `__qualname__` to ufuncs, to allow this more
+ # explicitly (Numba has ufuncs as attributes).
+ # See also: https://github.com/dask/distributed/issues/3450
+ 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)
+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__)
+del PytestTester
@@ -0,0 +1,6284 @@
+This is only meant to add docs to objects defined in C-extension modules.
+The purpose is to allow easier editing of the docstrings without
+requiring a re-compile.
+NOTE: Many of the methods of ndarray have corresponding functions.
+ If you update these docstrings, please keep also the ones in
+ core/fromnumeric.py, core/defmatrix.py up-to-date.
+from numpy.core.function_base import add_newdoc
+from numpy.core.overrides import array_function_like_doc
+###############################################################################
+# flatiter
+# flatiter needs a toplevel description
+add_newdoc('numpy.core', 'flatiter',
+ Flat iterator object to iterate over arrays.
+ A `flatiter` iterator is returned by ``x.flat`` for any array `x`.
+ It allows iterating over the array as if it were a 1-D array,
+ either in a for-loop or by calling its `next` method.
+ Iteration is done in row-major, C-style order (the last
+ index varying the fastest). The iterator can also be indexed using
+ basic slicing or advanced indexing.
+ ndarray.flat : Return a flat iterator over an array.
+ ndarray.flatten : Returns a flattened copy of an array.
+ A `flatiter` iterator can not be constructed directly from Python code
+ by calling the `flatiter` constructor.
+ >>> x = np.arange(6).reshape(2, 3)
+ >>> fl = x.flat
+ >>> type(fl)
+ <class 'numpy.flatiter'>
+ >>> for item in fl:
+ ... print(item)
+ 0
+ 1
+ 2
+ 3
+ 4
+ 5
+ >>> fl[2:4]
+ array([2, 3])
+ """)
+# flatiter attributes
+add_newdoc('numpy.core', 'flatiter', ('base',
+ A reference to the array that is iterated over.
+ >>> x = np.arange(5)
+ >>> fl.base is x
+ """))
+add_newdoc('numpy.core', 'flatiter', ('coords',
+ An N-dimensional tuple of current coordinates.
+ >>> fl.coords
+ (0, 0)
+ >>> next(fl)
+ (0, 1)
+add_newdoc('numpy.core', 'flatiter', ('index',
+ Current flat index into the array.
+ >>> fl.index
+# flatiter functions
+add_newdoc('numpy.core', 'flatiter', ('__array__',
+ """__array__(type=None) Get array from iterator
+add_newdoc('numpy.core', 'flatiter', ('copy',
+ copy()
+ Get a copy of the iterator as a 1-D array.
+ >>> x
+ array([[0, 1, 2],
+ [3, 4, 5]])
+ >>> fl.copy()
+ array([0, 1, 2, 3, 4, 5])
+# nditer
+add_newdoc('numpy.core', 'nditer',
+ nditer(op, flags=None, op_flags=None, op_dtypes=None, order='K', casting='safe', op_axes=None, itershape=None, buffersize=0)
+ Efficient multi-dimensional iterator object to iterate over arrays.
+ To get started using this object, see the
+ :ref:`introductory guide to array iteration <arrays.nditer>`.
+ op : ndarray or sequence of array_like
+ The array(s) to iterate over.
+ flags : sequence of str, optional
+ Flags to control the behavior of the iterator.
+ * ``buffered`` enables buffering when required.
+ * ``c_index`` causes a C-order index to be tracked.
+ * ``f_index`` causes a Fortran-order index to be tracked.
+ * ``multi_index`` causes a multi-index, or a tuple of indices
+ with one per iteration dimension, to be tracked.
+ * ``common_dtype`` causes all the operands to be converted to
+ a common data type, with copying or buffering as necessary.
+ * ``copy_if_overlap`` causes the iterator to determine if read
+ operands have overlap with write operands, and make temporary
+ copies as necessary to avoid overlap. False positives (needless
+ copying) are possible in some cases.
+ * ``delay_bufalloc`` delays allocation of the buffers until
+ a reset() call is made. Allows ``allocate`` operands to
+ be initialized before their values are copied into the buffers.
+ * ``external_loop`` causes the ``values`` given to be
+ one-dimensional arrays with multiple values instead of
+ zero-dimensional arrays.
+ * ``grow_inner`` allows the ``value`` array sizes to be made
+ larger than the buffer size when both ``buffered`` and
+ ``external_loop`` is used.
+ * ``ranged`` allows the iterator to be restricted to a sub-range
+ of the iterindex values.
+ * ``refs_ok`` enables iteration of reference types, such as
+ object arrays.
+ * ``reduce_ok`` enables iteration of ``readwrite`` operands
+ which are broadcasted, also known as reduction operands.
+ * ``zerosize_ok`` allows `itersize` to be zero.
+ op_flags : list of list of str, optional
+ This is a list of flags for each operand. At minimum, one of
+ ``readonly``, ``readwrite``, or ``writeonly`` must be specified.
+ * ``readonly`` indicates the operand will only be read from.
+ * ``readwrite`` indicates the operand will be read from and written to.
+ * ``writeonly`` indicates the operand will only be written to.
+ * ``no_broadcast`` prevents the operand from being broadcasted.
+ * ``contig`` forces the operand data to be contiguous.
+ * ``aligned`` forces the operand data to be aligned.
+ * ``nbo`` forces the operand data to be in native byte order.
+ * ``copy`` allows a temporary read-only copy if required.
+ * ``updateifcopy`` allows a temporary read-write copy if required.
+ * ``allocate`` causes the array to be allocated if it is None
+ in the ``op`` parameter.
+ * ``no_subtype`` prevents an ``allocate`` operand from using a subtype.
+ * ``arraymask`` indicates that this operand is the mask to use
+ for selecting elements when writing to operands with the
+ 'writemasked' flag set. The iterator does not enforce this,
+ but when writing from a buffer back to the array, it only
+ copies those elements indicated by this mask.
+ * ``writemasked`` indicates that only elements where the chosen
+ ``arraymask`` operand is True will be written to.
+ * ``overlap_assume_elementwise`` can be used to mark operands that are
+ accessed only in the iterator order, to allow less conservative
+ copying when ``copy_if_overlap`` is present.
+ op_dtypes : dtype or tuple of dtype(s), optional
+ The required data type(s) of the operands. If copying or buffering
+ is enabled, the data will be converted to/from their original types.
+ order : {'C', 'F', 'A', 'K'}, optional
+ Controls the iteration order. 'C' means C order, 'F' means
+ Fortran order, 'A' means 'F' order if all the arrays are Fortran
+ contiguous, 'C' order otherwise, and 'K' means as close to the
+ order the array elements appear in memory as possible. This also
+ affects the element memory order of ``allocate`` operands, as they
+ are allocated to be compatible with iteration order.
+ Default is 'K'.
+ casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional
+ Controls what kind of data casting may occur when making a copy
+ or buffering. Setting this to 'unsafe' is not recommended,
+ as it can adversely affect accumulations.
+ * 'no' means the data types should not be cast at all.
+ * 'equiv' means only byte-order changes are allowed.
+ * 'safe' means only casts which can preserve values are allowed.
+ * 'same_kind' means only safe casts or casts within a kind,
+ like float64 to float32, are allowed.
+ * 'unsafe' means any data conversions may be done.
+ op_axes : list of list of ints, optional
+ If provided, is a list of ints or None for each operands.
+ The list of axes for an operand is a mapping from the dimensions
+ of the iterator to the dimensions of the operand. A value of
+ -1 can be placed for entries, causing that dimension to be
+ treated as `newaxis`.
+ itershape : tuple of ints, optional
+ The desired shape of the iterator. This allows ``allocate`` operands
+ with a dimension mapped by op_axes not corresponding to a dimension
+ of a different operand to get a value not equal to 1 for that
+ dimension.
+ buffersize : int, optional
+ When buffering is enabled, controls the size of the temporary
+ buffers. Set to 0 for the default value.
+ dtypes : tuple of dtype(s)
+ The data types of the values provided in `value`. This may be
+ different from the operand data types if buffering is enabled.
+ Valid only before the iterator is closed.
+ finished : bool
+ Whether the iteration over the operands is finished or not.
+ has_delayed_bufalloc : bool
+ If True, the iterator was created with the ``delay_bufalloc`` flag,
+ and no reset() function was called on it yet.
+ has_index : bool
+ If True, the iterator was created with either the ``c_index`` or
+ the ``f_index`` flag, and the property `index` can be used to
+ retrieve it.
+ has_multi_index : bool
+ If True, the iterator was created with the ``multi_index`` flag,
+ and the property `multi_index` can be used to retrieve it.
+ index
+ When the ``c_index`` or ``f_index`` flag was used, this property
+ provides access to the index. Raises a ValueError if accessed
+ and ``has_index`` is False.
+ iterationneedsapi : bool
+ Whether iteration requires access to the Python API, for example
+ if one of the operands is an object array.
+ iterindex : int
+ An index which matches the order of iteration.
+ itersize : int
+ Size of the iterator.
+ itviews
+ Structured view(s) of `operands` in memory, matching the reordered
+ and optimized iterator access pattern. Valid only before the iterator
+ is closed.
+ multi_index
+ When the ``multi_index`` flag was used, this property
+ accessed and ``has_multi_index`` is False.
+ ndim : int
+ The dimensions of the iterator.
+ nop : int
+ The number of iterator operands.
+ operands : tuple of operand(s)
+ The array(s) to be iterated over. Valid only before the iterator is
+ closed.
+ shape : tuple of ints
+ Shape tuple, the shape of the iterator.
+ value
+ Value of ``operands`` at current iteration. Normally, this is a
+ tuple of array scalars, but if the flag ``external_loop`` is used,
+ it is a tuple of one dimensional arrays.
+ `nditer` supersedes `flatiter`. The iterator implementation behind
+ `nditer` is also exposed by the NumPy C API.
+ The Python exposure supplies two iteration interfaces, one which follows
+ the Python iterator protocol, and another which mirrors the C-style
+ do-while pattern. The native Python approach is better in most cases, but
+ if you need the coordinates or index of an iterator, use the C-style pattern.
+ Here is how we might write an ``iter_add`` function, using the
+ Python iterator protocol:
+ >>> def iter_add_py(x, y, out=None):
+ ... addop = np.add
+ ... it = np.nditer([x, y, out], [],
+ ... [['readonly'], ['readonly'], ['writeonly','allocate']])
+ ... with it:
+ ... for (a, b, c) in it:
+ ... addop(a, b, out=c)
+ ... return it.operands[2]
+ Here is the same function, but following the C-style pattern:
+ >>> def iter_add(x, y, out=None):
+ ... while not it.finished:
+ ... addop(it[0], it[1], out=it[2])
+ ... it.iternext()
+ Here is an example outer product function:
+ >>> def outer_it(x, y, out=None):
+ ... mulop = np.multiply
+ ... it = np.nditer([x, y, out], ['external_loop'],
+ ... [['readonly'], ['readonly'], ['writeonly', 'allocate']],
+ ... op_axes=[list(range(x.ndim)) + [-1] * y.ndim,
+ ... [-1] * x.ndim + list(range(y.ndim)),
+ ... None])
+ ... mulop(a, b, out=c)
+ >>> a = np.arange(2)+1
+ >>> b = np.arange(3)+1
+ >>> outer_it(a,b)
+ array([[1, 2, 3],
+ [2, 4, 6]])
+ Here is an example function which operates like a "lambda" ufunc:
+ >>> def luf(lamdaexpr, *args, **kwargs):
+ ... '''luf(lambdaexpr, op1, ..., opn, out=None, order='K', casting='safe', buffersize=0)'''
+ ... nargs = len(args)
+ ... op = (kwargs.get('out',None),) + args
+ ... it = np.nditer(op, ['buffered','external_loop'],
+ ... [['writeonly','allocate','no_broadcast']] +
+ ... [['readonly','nbo','aligned']]*nargs,
+ ... order=kwargs.get('order','K'),
+ ... casting=kwargs.get('casting','safe'),
+ ... buffersize=kwargs.get('buffersize',0))
+ ... it[0] = lamdaexpr(*it[1:])
+ ... return it.operands[0]
+ >>> a = np.arange(5)
+ >>> b = np.ones(5)
+ >>> luf(lambda i,j:i*i + j/2, a, b)
+ array([ 0.5, 1.5, 4.5, 9.5, 16.5])
+ If operand flags `"writeonly"` or `"readwrite"` are used the
+ operands may be views into the original data with the
+ `WRITEBACKIFCOPY` flag. In this case `nditer` must be used as a
+ context manager or the `nditer.close` method must be called before
+ using the result. The temporary data will be written back to the
+ original data when the `__exit__` function is called but not before:
+ >>> a = np.arange(6, dtype='i4')[::-2]
+ >>> with np.nditer(a, [],
+ ... [['writeonly', 'updateifcopy']],
+ ... casting='unsafe',
+ ... op_dtypes=[np.dtype('f4')]) as i:
+ ... x = i.operands[0]
+ ... x[:] = [-1, -2, -3]
+ ... # a still unchanged here
+ >>> a, x
+ (array([-1, -2, -3], dtype=int32), array([-1., -2., -3.], dtype=float32))
+ It is important to note that once the iterator is exited, dangling
+ references (like `x` in the example) may or may not share data with
+ the original data `a`. If writeback semantics were active, i.e. if
+ `x.base.flags.writebackifcopy` is `True`, then exiting the iterator
+ will sever the connection between `x` and `a`, writing to `x` will
+ no longer write to `a`. If writeback semantics are not active, then
+ `x.data` will still point at some part of `a.data`, and writing to
+ one will affect the other.
+ Context management and the `close` method appeared in version 1.15.0.
+# nditer methods
+add_newdoc('numpy.core', 'nditer', ('copy',
+ Get a copy of the iterator in its current state.
+ >>> x = np.arange(10)
+ >>> y = x + 1
+ >>> it = np.nditer([x, y])
+ >>> next(it)
+ (array(0), array(1))
+ >>> it2 = it.copy()
+ >>> next(it2)
+ (array(1), array(2))
+add_newdoc('numpy.core', 'nditer', ('operands',
+ operands[`Slice`]
+ The array(s) to be iterated over. Valid only before the iterator is closed.
+add_newdoc('numpy.core', 'nditer', ('debug_print',
+ debug_print()
+ Print the current state of the `nditer` instance and debug info to stdout.
+add_newdoc('numpy.core', 'nditer', ('enable_external_loop',
+ enable_external_loop()
+ When the "external_loop" was not used during construction, but
+ is desired, this modifies the iterator to behave as if the flag
+ was specified.
+add_newdoc('numpy.core', 'nditer', ('iternext',
+ iternext()
+ Check whether iterations are left, and perform a single internal iteration
+ without returning the result. Used in the C-style pattern do-while
+ pattern. For an example, see `nditer`.
+ iternext : bool
+ Whether or not there are iterations left.
+add_newdoc('numpy.core', 'nditer', ('remove_axis',
+ remove_axis(i)
+ Removes axis `i` from the iterator. Requires that the flag "multi_index"
+ be enabled.
+add_newdoc('numpy.core', 'nditer', ('remove_multi_index',
+ remove_multi_index()
+ When the "multi_index" flag was specified, this removes it, allowing
+ the internal iteration structure to be optimized further.
+add_newdoc('numpy.core', 'nditer', ('reset',
+ reset()
+ Reset the iterator to its initial state.
+add_newdoc('numpy.core', 'nested_iters',
+ Create nditers for use in nested loops
+ Create a tuple of `nditer` objects which iterate in nested loops over
+ different axes of the op argument. The first iterator is used in the
+ outermost loop, the last in the innermost loop. Advancing one will change
+ the subsequent iterators to point at its new element.
+ axes : list of list of int
+ Each item is used as an "op_axes" argument to an nditer
+ flags, op_flags, op_dtypes, order, casting, buffersize (optional)
+ See `nditer` parameters of the same name
+ iters : tuple of nditer
+ An nditer for each item in `axes`, outermost first
+ nditer
+ Basic usage. Note how y is the "flattened" version of
+ [a[:, 0, :], a[:, 1, 0], a[:, 2, :]] since we specified
+ the first iter's axes as [1]
+ >>> a = np.arange(12).reshape(2, 3, 2)
+ >>> i, j = np.nested_iters(a, [[1], [0, 2]], flags=["multi_index"])
+ >>> for x in i:
+ ... print(i.multi_index)
+ ... for y in j:
+ ... print('', j.multi_index, y)
+ (0,)
+ (0, 0) 0
+ (0, 1) 1
+ (1, 0) 6
+ (1, 1) 7
+ (1,)
+ (0, 0) 2
+ (0, 1) 3
+ (1, 0) 8
+ (1, 1) 9
+ (2,)
+ (0, 0) 4
+ (0, 1) 5
+ (1, 0) 10
+ (1, 1) 11
+add_newdoc('numpy.core', 'nditer', ('close',
+ close()
+ Resolve all writeback semantics in writeable operands.
+ .. versionadded:: 1.15.0
+ :ref:`nditer-context-manager`
+# broadcast
+add_newdoc('numpy.core', 'broadcast',
+ Produce an object that mimics broadcasting.
+ in1, in2, ... : array_like
+ Input parameters.
+ b : broadcast object
+ Broadcast the input parameters against one another, and
+ return an object that encapsulates the result.
+ Amongst others, it has ``shape`` and ``nd`` properties, and
+ may be used as an iterator.
+ broadcast_arrays
+ broadcast_to
+ broadcast_shapes
+ Manually adding two vectors, using broadcasting:
+ >>> x = np.array([[1], [2], [3]])
+ >>> y = np.array([4, 5, 6])
+ >>> b = np.broadcast(x, y)
+ >>> out = np.empty(b.shape)
+ >>> out.flat = [u+v for (u,v) in b]
+ >>> out
+ array([[5., 6., 7.],
+ [6., 7., 8.],
+ [7., 8., 9.]])
+ Compare against built-in broadcasting:
+ >>> x + y
+ array([[5, 6, 7],
+ [6, 7, 8],
+ [7, 8, 9]])
+# attributes
+add_newdoc('numpy.core', 'broadcast', ('index',
+ current index in broadcasted result
+ >>> b.index
+ >>> next(b), next(b), next(b)
+ ((1, 4), (1, 5), (1, 6))
+add_newdoc('numpy.core', 'broadcast', ('iters',
+ tuple of iterators along ``self``'s "components."
+ Returns a tuple of `numpy.flatiter` objects, one for each "component"
+ of ``self``.
+ numpy.flatiter
+ >>> x = np.array([1, 2, 3])
+ >>> y = np.array([[4], [5], [6]])
+ >>> row, col = b.iters
+ >>> next(row), next(col)
+ (1, 4)
+add_newdoc('numpy.core', 'broadcast', ('ndim',
+ Number of dimensions of broadcasted result. Alias for `nd`.
+ .. versionadded:: 1.12.0
+ >>> b.ndim
+add_newdoc('numpy.core', 'broadcast', ('nd',
+ Number of dimensions of broadcasted result. For code intended for NumPy
+ 1.12.0 and later the more consistent `ndim` is preferred.
+ >>> b.nd
+add_newdoc('numpy.core', 'broadcast', ('numiter',
+ Number of iterators possessed by the broadcasted result.
+ >>> b.numiter
+add_newdoc('numpy.core', 'broadcast', ('shape',
+ Shape of broadcasted result.
+ >>> b.shape
+ (3, 3)
+add_newdoc('numpy.core', 'broadcast', ('size',
+ Total size of broadcasted result.
+ >>> b.size
+ 9
+add_newdoc('numpy.core', 'broadcast', ('reset',
+ Reset the broadcasted result's iterator(s).
+ None
+ ((1, 4), (2, 4), (3, 4))
+ >>> b.reset()
+# numpy functions
+add_newdoc('numpy.core.multiarray', 'array',
+ array(object, dtype=None, *, copy=True, order='K', subok=False, ndmin=0,
+ like=None)
+ Create an array.
+ object : array_like
+ An array, any object exposing the array interface, an object whose
+ __array__ method returns an array, or any (nested) sequence.
+ 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
+ sequence.
+ copy : bool, optional
+ If true (default), then the object is copied. Otherwise, a copy will
+ only be made if __array__ returns a copy, if obj is a nested sequence,
+ or if a copy is needed to satisfy any of the other requirements
+ (`dtype`, `order`, etc.).
+ order : {'K', 'A', 'C', 'F'}, optional
+ Specify the memory layout of the array. If object is not an array, the
+ newly created array will be in C order (row major) unless 'F' is
+ specified, in which case it will be in Fortran order (column major).
+ If object is an array the following holds.
+ ===== ========= ===================================================
+ order no copy copy=True
+ 'K' unchanged F & C order preserved, otherwise most similar order
+ 'A' unchanged F order if input is F and not C, otherwise C order
+ 'C' C order C order
+ 'F' F order F order
+ 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
+ Notes section. The default order is 'K'.
+ 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).
+ ndmin : int, optional
+ Specifies the minimum number of dimensions that the resulting
+ array should have. Ones will be pre-pended to the shape as
+ needed to meet this requirement.
+ ${ARRAY_FUNCTION_LIKE}
+ .. versionadded:: 1.20.0
+ out : ndarray
+ An array object satisfying the specified requirements.
+ empty_like : Return an empty array with shape and type of input.
+ ones_like : Return an array of ones with shape and type of input.
+ zeros_like : Return an array of zeros with shape and type of input.
+ full_like : Return a new array with shape of input filled with value.
+ empty : Return a new uninitialized array.
+ ones : Return a new array setting values to one.
+ zeros : Return a new array setting values to zero.
+ full : Return a new array of given shape filled with value.
+ When order is 'A' and `object` is an array in neither 'C' nor 'F' order,
+ and a copy is forced by a change in dtype, then the order of the result is
+ not necessarily 'C' as expected. This is likely a bug.
+ >>> np.array([1, 2, 3])
+ array([1, 2, 3])
+ Upcasting:
+ >>> np.array([1, 2, 3.0])
+ array([ 1., 2., 3.])
+ More than one dimension:
+ >>> np.array([[1, 2], [3, 4]])
+ array([[1, 2],
+ [3, 4]])
+ Minimum dimensions 2:
+ >>> np.array([1, 2, 3], ndmin=2)
+ array([[1, 2, 3]])
+ Type provided:
+ >>> np.array([1, 2, 3], dtype=complex)
+ array([ 1.+0.j, 2.+0.j, 3.+0.j])
+ Data-type consisting of more than one element:
+ >>> x = np.array([(1,2),(3,4)],dtype=[('a','<i4'),('b','<i4')])
+ >>> x['a']
+ array([1, 3])
+ Creating an array from sub-classes:
+ >>> np.array(np.mat('1 2; 3 4'))
+ >>> np.array(np.mat('1 2; 3 4'), subok=True)
+ matrix([[1, 2],
+ """.replace(
+ "${ARRAY_FUNCTION_LIKE}",
+ array_function_like_doc,
+ ))
+add_newdoc('numpy.core.multiarray', 'empty',
+ empty(shape, dtype=float, order='C', *, like=None)
+ Return a new array of given shape and type, without initializing entries.
+ shape : int or tuple of int
+ Shape of the empty array, e.g., ``(2, 3)`` or ``2``.
+ Desired output data-type for the array, e.g, `numpy.int8`. Default is
+ `numpy.float64`.
+ order : {'C', 'F'}, optional, default: 'C'
+ Whether to store multi-dimensional data in row-major
+ (C-style) or column-major (Fortran-style) order in
+ memory.
+ Array of uninitialized (arbitrary) data of the given shape, dtype, and
+ order. Object arrays will be initialized to None.
+ `empty`, unlike `zeros`, does not set the array values to zero,
+ and may therefore be marginally faster. On the other hand, it requires
+ the user to manually set all the values in the array, and should be
+ used with caution.
+ >>> np.empty([2, 2])
+ array([[ -9.74499359e+001, 6.69583040e-309],
+ [ 2.13182611e-314, 3.06959433e-309]]) #uninitialized
+ >>> np.empty([2, 2], dtype=int)
+ array([[-1073741821, -1067949133],
+ [ 496041986, 19249760]]) #uninitialized
+add_newdoc('numpy.core.multiarray', 'scalar',
+ scalar(dtype, obj)
+ Return a new scalar array of the given type initialized with obj.
+ This function is meant mainly for pickle support. `dtype` must be a
+ valid data-type descriptor. If `dtype` corresponds to an object
+ descriptor, then `obj` can be any object, otherwise `obj` must be a
+ string. If `obj` is not given, it will be interpreted as None for object
+ type and as zeros for all other types.
+add_newdoc('numpy.core.multiarray', 'zeros',
+ zeros(shape, dtype=float, order='C', *, like=None)
+ Return a new array of given shape and type, filled with zeros.
+ shape : int or tuple of ints
+ Shape of the new array, e.g., ``(2, 3)`` or ``2``.
+ The desired data-type for the array, e.g., `numpy.int8`. Default is
+ Array of zeros with the given shape, dtype, and order.
+ >>> np.zeros(5)
+ array([ 0., 0., 0., 0., 0.])
+ >>> np.zeros((5,), dtype=int)
+ array([0, 0, 0, 0, 0])
+ >>> np.zeros((2, 1))
+ array([[ 0.],
+ [ 0.]])
+ >>> s = (2,2)
+ >>> np.zeros(s)
+ array([[ 0., 0.],
+ [ 0., 0.]])
+ >>> np.zeros((2,), dtype=[('x', 'i4'), ('y', 'i4')]) # custom dtype
+ array([(0, 0), (0, 0)],
+ dtype=[('x', '<i4'), ('y', '<i4')])
+add_newdoc('numpy.core.multiarray', 'set_typeDict',
+ """set_typeDict(dict)
+ Set the internal dictionary that can look up an array type using a
+ registered code.
+add_newdoc('numpy.core.multiarray', 'fromstring',
+ fromstring(string, dtype=float, count=-1, sep='', *, like=None)
+ A new 1-D array initialized from text data in a string.
+ string : str
+ A string containing the data.
+ The data type of the array; default: float. For binary input data,
+ the data must be in exactly this format. Most builtin numeric types are
+ supported and extension types may be supported.
+ .. versionadded:: 1.18.0
+ Complex dtypes.
+ count : int, optional
+ Read this number of `dtype` elements from the data. If this is
+ negative (the default), the count will be determined from the
+ length of the data.
+ sep : str, optional
+ The string separating numbers in the data; extra whitespace between
+ elements is also ignored.
+ .. deprecated:: 1.14
+ Passing ``sep=''``, the default, is deprecated since it will
+ trigger the deprecated binary mode of this function. This mode
+ interprets `string` as binary bytes, rather than ASCII text with
+ decimal numbers, an operation which is better spelt
+ ``frombuffer(string, dtype, count)``. If `string` contains unicode
+ text, the binary mode of `fromstring` will first encode it into
+ bytes using either utf-8 (python 3) or the default encoding
+ (python 2), neither of which produce sane results.
+ arr : ndarray
+ The constructed array.
+ Raises
+ ------
+ ValueError
+ If the string is not the correct size to satisfy the requested
+ `dtype` and `count`.
+ frombuffer, fromfile, fromiter
+ >>> np.fromstring('1 2', dtype=int, sep=' ')
+ array([1, 2])
+ >>> np.fromstring('1, 2', dtype=int, sep=',')
+add_newdoc('numpy.core.multiarray', 'compare_chararrays',
+ compare_chararrays(a, b, cmp_op, rstrip)
+ Performs element-wise comparison of two string arrays using the
+ comparison operator specified by `cmp_op`.
+ a, b : array_like
+ Arrays to be compared.
+ cmp_op : {"<", "<=", "==", ">=", ">", "!="}
+ Type of comparison.
+ rstrip : Boolean
+ If True, the spaces at the end of Strings are removed before the comparison.
+ The output array of type Boolean with the same shape as a and b.
+ If `cmp_op` is not valid.
+ TypeError
+ If at least one of `a` or `b` is a non-string array
+ >>> a = np.array(["a", "b", "cde"])
+ >>> b = np.array(["a", "a", "dec"])
+ >>> np.compare_chararrays(a, b, ">", True)
+ array([False, True, False])
+add_newdoc('numpy.core.multiarray', 'fromiter',
+ fromiter(iterable, dtype, count=-1, *, like=None)
+ Create a new 1-dimensional array from an iterable object.
+ iterable : iterable object
+ An iterable object providing data for the array.
+ dtype : data-type
+ The data-type of the returned array.
+ The number of items to read from *iterable*. The default is -1,
+ which means all data is read.
+ The output array.
+ Specify `count` to improve performance. It allows ``fromiter`` to
+ pre-allocate the output array, instead of resizing it on demand.
+ >>> iterable = (x*x for x in range(5))
+ >>> np.fromiter(iterable, float)
+ array([ 0., 1., 4., 9., 16.])
+add_newdoc('numpy.core.multiarray', 'fromfile',
+ fromfile(file, dtype=float, count=-1, sep='', offset=0, *, like=None)
+ Construct an array from data in a text or binary file.
+ A highly efficient way of reading binary data with a known data-type,
+ as well as parsing simply formatted text files. Data written using the
+ `tofile` method can be read using this function.
+ file : file or str or Path
+ Open file object or filename.
+ .. versionchanged:: 1.17.0
+ `pathlib.Path` objects are now accepted.
+ Data type of the returned array.
+ For binary files, it is used to determine the size and byte-order
+ of the items in the file.
+ Most builtin numeric types are supported and extension types may be supported.
+ count : int
+ Number of items to read. ``-1`` means all items (i.e., the complete
+ file).
+ sep : str
+ Separator between items if file is a text file.
+ Empty ("") separator means the file should be treated as binary.
+ Spaces (" ") in the separator match zero or more whitespace characters.
+ A separator consisting only of spaces must match at least one
+ whitespace.
+ offset : int
+ The offset (in bytes) from the file's current position. Defaults to 0.
+ Only permitted for binary files.
+ .. versionadded:: 1.17.0
+ See also
+ load, save
+ ndarray.tofile
+ loadtxt : More flexible way of loading data from a text file.
+ Do not rely on the combination of `tofile` and `fromfile` for
+ data storage, as the binary files generated are not platform
+ independent. In particular, no byte-order or data-type information is
+ saved. Data can be stored in the platform independent ``.npy`` format
+ using `save` and `load` instead.
+ Construct an ndarray:
+ >>> dt = np.dtype([('time', [('min', np.int64), ('sec', np.int64)]),
+ ... ('temp', float)])
+ >>> x = np.zeros((1,), dtype=dt)
+ >>> x['time']['min'] = 10; x['temp'] = 98.25
+ array([((10, 0), 98.25)],
+ dtype=[('time', [('min', '<i8'), ('sec', '<i8')]), ('temp', '<f8')])
+ Save the raw data to disk:
+ >>> import tempfile
+ >>> fname = tempfile.mkstemp()[1]
+ >>> x.tofile(fname)
+ Read the raw data from disk:
+ >>> np.fromfile(fname, dtype=dt)
+ The recommended way to store and load data:
+ >>> np.save(fname, x)
+ >>> np.load(fname + '.npy')
+add_newdoc('numpy.core.multiarray', 'frombuffer',
+ frombuffer(buffer, dtype=float, count=-1, offset=0, *, like=None)
+ Interpret a buffer as a 1-dimensional array.
+ buffer : buffer_like
+ An object that exposes the buffer interface.
+ Data-type of the returned array; default: float.
+ Number of items to read. ``-1`` means all data in the buffer.
+ offset : int, optional
+ Start reading the buffer from this offset (in bytes); default: 0.
+ If the buffer has data that is not in machine byte-order, this should
+ be specified as part of the data-type, e.g.::
+ >>> dt = np.dtype(int)
+ >>> dt = dt.newbyteorder('>')
+ >>> np.frombuffer(buf, dtype=dt) # doctest: +SKIP
+ The data of the resulting array will not be byteswapped, but will be
+ interpreted correctly.
+ >>> s = b'hello world'
+ >>> np.frombuffer(s, dtype='S1', count=5, offset=6)
+ array([b'w', b'o', b'r', b'l', b'd'], dtype='|S1')
+ >>> np.frombuffer(b'\\x01\\x02', dtype=np.uint8)
+ array([1, 2], dtype=uint8)
+ >>> np.frombuffer(b'\\x01\\x02\\x03\\x04\\x05', dtype=np.uint8, count=3)
+ array([1, 2, 3], dtype=uint8)
+add_newdoc('numpy.core', 'fastCopyAndTranspose',
+ """_fastCopyAndTranspose(a)""")
+add_newdoc('numpy.core.multiarray', 'correlate',
+ """cross_correlate(a,v, mode=0)""")
+add_newdoc('numpy.core.multiarray', 'arange',
+ arange([start,] stop[, step,], dtype=None, *, like=None)
+ Return evenly spaced values within a given interval.
+ Values are generated within the half-open interval ``[start, stop)``
+ (in other words, the interval including `start` but excluding `stop`).
+ 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.
+ start : integer or real, optional
+ Start of interval. The interval includes this value. The default
+ start value is 0.
+ stop : integer or real
+ End of interval. The interval does not include this value, except
+ in some cases where `step` is not an integer and floating point
+ round-off affects the length of `out`.
+ step : integer or real, optional
+ Spacing between values. For any output `out`, this is the distance
+ between two adjacent values, ``out[i+1] - out[i]``. The default
+ step size is 1. If `step` is specified as a position argument,
+ `start` must also be given.
+ dtype : dtype
+ The type of the output array. If `dtype` is not given, infer the data
+ type from the other input arguments.
+ arange : ndarray
+ Array of evenly spaced values.
+ For floating point arguments, the length of the result is
+ ``ceil((stop - start)/step)``. Because of floating point overflow,
+ this rule may result in the last element of `out` being greater
+ than `stop`.
+ numpy.linspace : Evenly spaced numbers with careful handling of endpoints.
+ numpy.ogrid: Arrays of evenly spaced numbers in N-dimensions.
+ numpy.mgrid: Grid-shaped arrays of evenly spaced numbers in N-dimensions.
+ >>> np.arange(3)
+ array([0, 1, 2])
+ >>> np.arange(3.0)
+ array([ 0., 1., 2.])
+ >>> np.arange(3,7)
+ array([3, 4, 5, 6])
+ >>> np.arange(3,7,2)
+ array([3, 5])
+add_newdoc('numpy.core.multiarray', '_get_ndarray_c_version',
+ """_get_ndarray_c_version()
+ Return the compile time NPY_VERSION (formerly called NDARRAY_VERSION) number.
+add_newdoc('numpy.core.multiarray', '_reconstruct',
+ """_reconstruct(subtype, shape, dtype)
+ Construct an empty array. Used by Pickles.
+add_newdoc('numpy.core.multiarray', 'set_string_function',
+ set_string_function(f, repr=1)
+ Internal method to set a function to be used when pretty printing arrays.
+add_newdoc('numpy.core.multiarray', 'set_numeric_ops',
+ set_numeric_ops(op1=func1, op2=func2, ...)
+ Set numerical operators for array objects.
+ .. deprecated:: 1.16
+ For the general case, use :c:func:`PyUFunc_ReplaceLoopBySignature`.
+ For ndarray subclasses, define the ``__array_ufunc__`` method and
+ override the relevant ufunc.
+ op1, op2, ... : callable
+ Each ``op = func`` pair describes an operator to be replaced.
+ For example, ``add = lambda x, y: np.add(x, y) % 5`` would replace
+ addition by modulus 5 addition.
+ saved_ops : list of callables
+ A list of all operators, stored before making replacements.
+ .. WARNING::
+ Use with care! Incorrect usage may lead to memory errors.
+ A function replacing an operator cannot make use of that operator.
+ For example, when replacing add, you may not use ``+``. Instead,
+ directly call ufuncs.
+ >>> def add_mod5(x, y):
+ ... return np.add(x, y) % 5
+ >>> old_funcs = np.set_numeric_ops(add=add_mod5)
+ >>> x = np.arange(12).reshape((3, 4))
+ >>> x + x
+ array([[0, 2, 4, 1],
+ [3, 0, 2, 4],
+ [1, 3, 0, 2]])
+ >>> ignore = np.set_numeric_ops(**old_funcs) # restore operators
+add_newdoc('numpy.core.multiarray', 'promote_types',
+ promote_types(type1, type2)
+ Returns the data type with the smallest size and smallest scalar
+ kind to which both ``type1`` and ``type2`` may be safely cast.
+ The returned data type is always in native byte order.
+ This function is symmetric, but rarely associative.
+ type1 : dtype or dtype specifier
+ First data type.
+ type2 : dtype or dtype specifier
+ Second data type.
+ out : dtype
+ The promoted data type.
+ .. versionadded:: 1.6.0
+ Starting in NumPy 1.9, promote_types function now returns a valid string
+ length when given an integer or float dtype as one argument and a string
+ dtype as another argument. Previously it always returned the input string
+ dtype, even if it wasn't long enough to store the max integer/float value
+ converted to a string.
+ result_type, dtype, can_cast
+ >>> np.promote_types('f4', 'f8')
+ dtype('float64')
+ >>> np.promote_types('i8', 'f4')
+ >>> np.promote_types('>i8', '<c8')
+ dtype('complex128')
+ >>> np.promote_types('i4', 'S8')
+ dtype('S11')
+ An example of a non-associative case:
+ >>> p = np.promote_types
+ >>> p('S', p('i1', 'u1'))
+ dtype('S6')
+ >>> p(p('S', 'i1'), 'u1')
+ dtype('S4')
+add_newdoc('numpy.core.multiarray', 'c_einsum',
+ c_einsum(subscripts, *operands, out=None, dtype=None, order='K',
+ casting='safe')
+ *This documentation shadows that of the native python implementation of the `einsum` function,
+ except all references and examples related to the `optimize` argument (v 0.12.0) have been removed.*
+ Evaluates the Einstein summation convention on the operands.
+ Using the Einstein summation convention, many common multi-dimensional,
+ linear algebraic array operations can be represented in a simple fashion.
+ In *implicit* mode `einsum` computes these values.
+ In *explicit* mode, `einsum` provides further flexibility to compute
+ other array operations that might not be considered classical Einstein
+ summation operations, by disabling, or forcing summation over specified
+ subscript labels.
+ See the notes and examples for clarification.
+ subscripts : str
+ Specifies the subscripts for summation as comma separated list of
+ subscript labels. An implicit (classical Einstein summation)
+ calculation is performed unless the explicit indicator '->' is
+ included as well as subscript labels of the precise output form.
+ operands : list of array_like
+ These are the arrays for the operation.
+ out : ndarray, optional
+ If provided, the calculation is done into this array.
+ dtype : {data-type, None}, optional
+ If provided, forces the calculation to use the data type specified.
+ Note that you may have to also give a more liberal `casting`
+ parameter to allow the conversions. Default is None.
+ Controls the memory layout of the output. 'C' means it should
+ be C contiguous. 'F' means it should be Fortran contiguous,
+ 'A' means it should be 'F' if the inputs are all 'F', 'C' otherwise.
+ 'K' means it should be as close to the layout of the inputs as
+ is possible, including arbitrarily permuted axes.
+ Controls what kind of data casting may occur. Setting this to
+ 'unsafe' is not recommended, as it can adversely affect accumulations.
+ Default is 'safe'.
+ optimize : {False, True, 'greedy', 'optimal'}, optional
+ Controls if intermediate optimization should occur. No optimization
+ will occur if False and True will default to the 'greedy' algorithm.
+ Also accepts an explicit contraction list from the ``np.einsum_path``
+ function. See ``np.einsum_path`` for more details. Defaults to False.
+ output : ndarray
+ The calculation based on the Einstein summation convention.
+ einsum_path, dot, inner, outer, tensordot, linalg.multi_dot
+ The Einstein summation convention can be used to compute
+ many multi-dimensional, linear algebraic array operations. `einsum`
+ provides a succinct way of representing these.
+ A non-exhaustive list of these operations,
+ which can be computed by `einsum`, is shown below along with examples:
+ * Trace of an array, :py:func:`numpy.trace`.
+ * Return a diagonal, :py:func:`numpy.diag`.
+ * Array axis summations, :py:func:`numpy.sum`.
+ * Transpositions and permutations, :py:func:`numpy.transpose`.
+ * Matrix multiplication and dot product, :py:func:`numpy.matmul` :py:func:`numpy.dot`.
+ * Vector inner and outer products, :py:func:`numpy.inner` :py:func:`numpy.outer`.
+ * Broadcasting, element-wise and scalar multiplication, :py:func:`numpy.multiply`.
+ * Tensor contractions, :py:func:`numpy.tensordot`.
+ * Chained array operations, in efficient calculation order, :py:func:`numpy.einsum_path`.
+ The subscripts string is a comma-separated list of subscript labels,
+ where each label refers to a dimension of the corresponding operand.
+ Whenever a label is repeated it is summed, so ``np.einsum('i,i', a, b)``
+ is equivalent to :py:func:`np.inner(a,b) <numpy.inner>`. If a label
+ appears only once, it is not summed, so ``np.einsum('i', a)`` produces a
+ view of ``a`` with no changes. A further example ``np.einsum('ij,jk', a, b)``
+ describes traditional matrix multiplication and is equivalent to
+ :py:func:`np.matmul(a,b) <numpy.matmul>`. Repeated subscript labels in one
+ operand take the diagonal. For example, ``np.einsum('ii', a)`` is equivalent
+ to :py:func:`np.trace(a) <numpy.trace>`.
+ In *implicit mode*, the chosen subscripts are important
+ since the axes of the output are reordered alphabetically. This
+ means that ``np.einsum('ij', a)`` doesn't affect a 2D array, while
+ ``np.einsum('ji', a)`` takes its transpose. Additionally,
+ ``np.einsum('ij,jk', a, b)`` returns a matrix multiplication, while,
+ ``np.einsum('ij,jh', a, b)`` returns the transpose of the
+ multiplication since subscript 'h' precedes subscript 'i'.
+ In *explicit mode* the output can be directly controlled by
+ specifying output subscript labels. This requires the
+ identifier '->' as well as the list of output subscript labels.
+ This feature increases the flexibility of the function since
+ summing can be disabled or forced when required. The call
+ ``np.einsum('i->', a)`` is like :py:func:`np.sum(a, axis=-1) <numpy.sum>`,
+ and ``np.einsum('ii->i', a)`` is like :py:func:`np.diag(a) <numpy.diag>`.
+ The difference is that `einsum` does not allow broadcasting by default.
+ Additionally ``np.einsum('ij,jh->ih', a, b)`` directly specifies the
+ order of the output subscript labels and therefore returns matrix
+ multiplication, unlike the example above in implicit mode.
+ To enable and control broadcasting, use an ellipsis. Default
+ NumPy-style broadcasting is done by adding an ellipsis
+ to the left of each term, like ``np.einsum('...ii->...i', a)``.
+ To take the trace along the first and last axes,
+ you can do ``np.einsum('i...i', a)``, or to do a matrix-matrix
+ product with the left-most indices instead of rightmost, one can do
+ ``np.einsum('ij...,jk...->ik...', a, b)``.
+ When there is only one operand, no axes are summed, and no output
+ parameter is provided, a view into the operand is returned instead
+ of a new array. Thus, taking the diagonal as ``np.einsum('ii->i', a)``
+ produces a view (changed in version 1.10.0).
+ `einsum` also provides an alternative way to provide the subscripts
+ and operands as ``einsum(op0, sublist0, op1, sublist1, ..., [sublistout])``.
+ If the output shape is not provided in this format `einsum` will be
+ calculated in implicit mode, otherwise it will be performed explicitly.
+ The examples below have corresponding `einsum` calls with the two
+ parameter methods.
+ .. versionadded:: 1.10.0
+ Views returned from einsum are now writeable whenever the input array
+ is writeable. For example, ``np.einsum('ijk...->kji...', a)`` will now
+ have the same effect as :py:func:`np.swapaxes(a, 0, 2) <numpy.swapaxes>`
+ and ``np.einsum('ii->i', a)`` will return a writeable view of the diagonal
+ of a 2D array.
+ >>> a = np.arange(25).reshape(5,5)
+ >>> b = np.arange(5)
+ >>> c = np.arange(6).reshape(2,3)
+ Trace of a matrix:
+ >>> np.einsum('ii', a)
+ 60
+ >>> np.einsum(a, [0,0])
+ >>> np.trace(a)
+ Extract the diagonal (requires explicit form):
+ >>> np.einsum('ii->i', a)
+ array([ 0, 6, 12, 18, 24])
+ >>> np.einsum(a, [0,0], [0])
+ >>> np.diag(a)
+ Sum over an axis (requires explicit form):
+ >>> np.einsum('ij->i', a)
+ array([ 10, 35, 60, 85, 110])
+ >>> np.einsum(a, [0,1], [0])
+ >>> np.sum(a, axis=1)
+ For higher dimensional arrays summing a single axis can be done with ellipsis:
+ >>> np.einsum('...j->...', a)
+ >>> np.einsum(a, [Ellipsis,1], [Ellipsis])
+ Compute a matrix transpose, or reorder any number of axes:
+ >>> np.einsum('ji', c)
+ array([[0, 3],
+ [1, 4],
+ [2, 5]])
+ >>> np.einsum('ij->ji', c)
+ >>> np.einsum(c, [1,0])
+ >>> np.transpose(c)
+ Vector inner products:
+ >>> np.einsum('i,i', b, b)
+ 30
+ >>> np.einsum(b, [0], b, [0])
+ >>> np.inner(b,b)
+ Matrix vector multiplication:
+ >>> np.einsum('ij,j', a, b)
+ array([ 30, 80, 130, 180, 230])
+ >>> np.einsum(a, [0,1], b, [1])
+ >>> np.dot(a, b)
+ >>> np.einsum('...j,j', a, b)
+ Broadcasting and scalar multiplication:
+ >>> np.einsum('..., ...', 3, c)
+ array([[ 0, 3, 6],
+ [ 9, 12, 15]])
+ >>> np.einsum(',ij', 3, c)
+ >>> np.einsum(3, [Ellipsis], c, [Ellipsis])
+ >>> np.multiply(3, c)
+ Vector outer product:
+ >>> np.einsum('i,j', np.arange(2)+1, b)
+ array([[0, 1, 2, 3, 4],
+ [0, 2, 4, 6, 8]])
+ >>> np.einsum(np.arange(2)+1, [0], b, [1])
+ >>> np.outer(np.arange(2)+1, b)
+ Tensor contraction:
+ >>> a = np.arange(60.).reshape(3,4,5)
+ >>> b = np.arange(24.).reshape(4,3,2)
+ >>> np.einsum('ijk,jil->kl', a, b)
+ array([[ 4400., 4730.],
+ [ 4532., 4874.],
+ [ 4664., 5018.],
+ [ 4796., 5162.],
+ [ 4928., 5306.]])
+ >>> np.einsum(a, [0,1,2], b, [1,0,3], [2,3])
+ >>> np.tensordot(a,b, axes=([1,0],[0,1]))
+ Writeable returned arrays (since version 1.10.0):
+ >>> a = np.zeros((3, 3))
+ >>> np.einsum('ii->i', a)[:] = 1
+ >>> a
+ array([[ 1., 0., 0.],
+ [ 0., 1., 0.],
+ [ 0., 0., 1.]])
+ Example of ellipsis use:
+ >>> a = np.arange(6).reshape((3,2))
+ >>> b = np.arange(12).reshape((4,3))
+ >>> np.einsum('ki,jk->ij', a, b)
+ array([[10, 28, 46, 64],
+ [13, 40, 67, 94]])
+ >>> np.einsum('ki,...k->i...', a, b)
+ >>> np.einsum('k...,jk', a, b)
+##############################################################################
+# Documentation for ndarray attributes and methods
+# ndarray object
+add_newdoc('numpy.core.multiarray', 'ndarray',
+ ndarray(shape, dtype=float, buffer=None, offset=0,
+ strides=None, order=None)
+ An array object represents a multidimensional, homogeneous array
+ of fixed-size items. An associated data-type object describes the
+ format of each element in the array (its byte-order, how many bytes it
+ occupies in memory, whether it is an integer, a floating point number,
+ or something else, etc.)
+ Arrays should be constructed using `array`, `zeros` or `empty` (refer
+ to the See Also section below). The parameters given here refer to
+ a low-level method (`ndarray(...)`) for instantiating an array.
+ For more information, refer to the `numpy` module and examine the
+ methods and attributes of an array.
+ (for the __new__ method; see Notes below)
+ Shape of created array.
+ Any object that can be interpreted as a numpy data type.
+ buffer : object exposing buffer interface, optional
+ Used to fill the array with data.
+ Offset of array data in buffer.
+ strides : tuple of ints, optional
+ Strides of data in memory.
+ order : {'C', 'F'}, optional
+ Row-major (C-style) or column-major (Fortran-style) order.
+ T : ndarray
+ Transpose of the array.
+ data : buffer
+ The array's elements, in memory.
+ dtype : dtype object
+ Describes the format of the elements in the array.
+ flags : dict
+ Dictionary containing information related to memory use, e.g.,
+ 'C_CONTIGUOUS', 'OWNDATA', 'WRITEABLE', etc.
+ flat : numpy.flatiter object
+ Flattened version of the array as an iterator. The iterator
+ allows assignments, e.g., ``x.flat = 3`` (See `ndarray.flat` for
+ assignment examples; TODO).
+ imag : ndarray
+ Imaginary part of the array.
+ real : ndarray
+ Real part of the array.
+ size : int
+ Number of elements in the array.
+ itemsize : int
+ The memory use of each array element in bytes.
+ nbytes : int
+ The total number of bytes required to store the array data,
+ i.e., ``itemsize * size``.
+ The array's number of dimensions.
+ Shape of the array.
+ strides : tuple of ints
+ The step-size required to move from one element to the next in
+ memory. For example, a contiguous ``(3, 4)`` array of type
+ ``int16`` in C-order has strides ``(8, 2)``. This implies that
+ to move from element to element in memory requires jumps of 2 bytes.
+ To move from row-to-row, one needs to jump 8 bytes at a time
+ (``2 * 4``).
+ ctypes : ctypes object
+ Class containing properties of the array needed for interaction
+ with ctypes.
+ base : ndarray
+ If the array is a view into another array, that array is its `base`
+ (unless that array is also a view). The `base` array is where the
+ array data is actually stored.
+ array : Construct an array.
+ zeros : Create an array, each element of which is zero.
+ empty : Create an array, but leave its allocated memory unchanged (i.e.,
+ it contains "garbage").
+ dtype : Create a data-type.
+ There are two modes of creating an array using ``__new__``:
+ 1. If `buffer` is None, then only `shape`, `dtype`, and `order`
+ are used.
+ 2. If `buffer` is an object exposing the buffer interface, then
+ all keywords are interpreted.
+ No ``__init__`` method is needed because the array is fully initialized
+ after the ``__new__`` method.
+ These examples illustrate the low-level `ndarray` constructor. Refer
+ to the `See Also` section above for easier ways of constructing an
+ ndarray.
+ First mode, `buffer` is None:
+ >>> np.ndarray(shape=(2,2), dtype=float, order='F')
+ array([[0.0e+000, 0.0e+000], # random
+ [ nan, 2.5e-323]])
+ Second mode:
+ >>> np.ndarray((2,), buffer=np.array([1,2,3]),
+ ... offset=np.int_().itemsize,
+ ... dtype=int) # offset = 1*itemsize, i.e. skip first element
+# ndarray attributes
+add_newdoc('numpy.core.multiarray', 'ndarray', ('__array_interface__',
+ """Array protocol: Python side."""))
+add_newdoc('numpy.core.multiarray', 'ndarray', ('__array_finalize__',
+ """None."""))
+add_newdoc('numpy.core.multiarray', 'ndarray', ('__array_priority__',
+ """Array priority."""))
+add_newdoc('numpy.core.multiarray', 'ndarray', ('__array_struct__',
+ """Array protocol: C-struct side."""))
+add_newdoc('numpy.core.multiarray', 'ndarray', ('base',
+ Base object if memory is from some other object.
+ The base of an array that owns its memory is None:
+ >>> x = np.array([1,2,3,4])
+ >>> x.base is None
+ Slicing creates a view, whose memory is shared with x:
+ >>> y = x[2:]
+ >>> y.base is x
+add_newdoc('numpy.core.multiarray', 'ndarray', ('ctypes',
+ An object to simplify the interaction of the array with the ctypes
+ module.
+ This attribute creates an object that makes it easier to use arrays
+ when calling shared libraries with the ctypes module. The returned
+ object has, among others, data, shape, and strides attributes (see
+ Notes below) which themselves return ctypes objects that can be used
+ as arguments to a shared library.
+ c : Python object
+ Possessing attributes data, shape, strides, etc.
+ numpy.ctypeslib
+ Below are the public attributes of this object which were documented
+ in "Guide to NumPy" (we have omitted undocumented public attributes,
+ as well as documented private attributes):
+ .. autoattribute:: numpy.core._internal._ctypes.data
+ :noindex:
+ .. autoattribute:: numpy.core._internal._ctypes.shape
+ .. autoattribute:: numpy.core._internal._ctypes.strides
+ .. automethod:: numpy.core._internal._ctypes.data_as
+ .. automethod:: numpy.core._internal._ctypes.shape_as
+ .. automethod:: numpy.core._internal._ctypes.strides_as
+ If the ctypes module is not available, then the ctypes attribute
+ of array objects still returns something useful, but ctypes objects
+ are not returned and errors may be raised instead. In particular,
+ the object will still have the ``as_parameter`` attribute which will
+ return an integer equal to the data attribute.
+ >>> import ctypes
+ >>> x = np.array([[0, 1], [2, 3]], dtype=np.int32)
+ array([[0, 1],
+ [2, 3]], dtype=int32)
+ >>> x.ctypes.data
+ 31962608 # may vary
+ >>> x.ctypes.data_as(ctypes.POINTER(ctypes.c_uint32))
+ <__main__.LP_c_uint object at 0x7ff2fc1fc200> # may vary
+ >>> x.ctypes.data_as(ctypes.POINTER(ctypes.c_uint32)).contents
+ c_uint(0)
+ >>> x.ctypes.data_as(ctypes.POINTER(ctypes.c_uint64)).contents
+ c_ulong(4294967296)
+ >>> x.ctypes.shape
+ <numpy.core._internal.c_long_Array_2 object at 0x7ff2fc1fce60> # may vary
+ >>> x.ctypes.strides
+ <numpy.core._internal.c_long_Array_2 object at 0x7ff2fc1ff320> # may vary
+add_newdoc('numpy.core.multiarray', 'ndarray', ('data',
+ """Python buffer object pointing to the start of the array's data."""))
+add_newdoc('numpy.core.multiarray', 'ndarray', ('dtype',
+ Data-type of the array's elements.
+ d : numpy dtype object
+ numpy.dtype
+ [2, 3]])
+ >>> x.dtype
+ dtype('int32')
+ >>> type(x.dtype)
+ <type 'numpy.dtype'>
+add_newdoc('numpy.core.multiarray', 'ndarray', ('imag',
+ The imaginary part of the array.
+ >>> x = np.sqrt([1+0j, 0+1j])
+ >>> x.imag
+ array([ 0. , 0.70710678])
+ >>> x.imag.dtype
+add_newdoc('numpy.core.multiarray', 'ndarray', ('itemsize',
+ Length of one array element in bytes.
+ >>> x = np.array([1,2,3], dtype=np.float64)
+ >>> x.itemsize
+ 8
+ >>> x = np.array([1,2,3], dtype=np.complex128)
+ 16
+add_newdoc('numpy.core.multiarray', 'ndarray', ('flags',
+ Information about the memory layout of the array.
+ C_CONTIGUOUS (C)
+ The data is in a single, C-style contiguous segment.
+ F_CONTIGUOUS (F)
+ The data is in a single, Fortran-style contiguous segment.
+ OWNDATA (O)
+ The array owns the memory it uses or borrows it from another object.
+ WRITEABLE (W)
+ The data area can be written to. Setting this to False locks
+ the data, making it read-only. A view (slice, etc.) inherits WRITEABLE
+ from its base array at creation time, but a view of a writeable
+ array may be subsequently locked while the base array remains writeable.
+ (The opposite is not true, in that a view of a locked array may not
+ be made writeable. However, currently, locking a base object does not
+ lock any views that already reference it, so under that circumstance it
+ is possible to alter the contents of a locked array via a previously
+ created writeable view onto it.) Attempting to change a non-writeable
+ array raises a RuntimeError exception.
+ ALIGNED (A)
+ The data and all elements are aligned appropriately for the hardware.
+ WRITEBACKIFCOPY (X)
+ This array is a copy of some other array. The C-API function
+ PyArray_ResolveWritebackIfCopy must be called before deallocating
+ to the base array will be updated with the contents of this array.
+ UPDATEIFCOPY (U)
+ (Deprecated, use WRITEBACKIFCOPY) This array is a copy of some other array.
+ When this array is
+ deallocated, the base array will be updated with the contents of
+ this array.
+ FNC
+ F_CONTIGUOUS and not C_CONTIGUOUS.
+ FORC
+ F_CONTIGUOUS or C_CONTIGUOUS (one-segment test).
+ BEHAVED (B)
+ ALIGNED and WRITEABLE.
+ CARRAY (CA)
+ BEHAVED and C_CONTIGUOUS.
+ FARRAY (FA)
+ BEHAVED and F_CONTIGUOUS and not C_CONTIGUOUS.
+ The `flags` object can be accessed dictionary-like (as in ``a.flags['WRITEABLE']``),
+ or by using lowercased attribute names (as in ``a.flags.writeable``). Short flag
+ names are only supported in dictionary access.
+ Only the WRITEBACKIFCOPY, UPDATEIFCOPY, WRITEABLE, and ALIGNED flags can be
+ changed by the user, via direct assignment to the attribute or dictionary
+ entry, or by calling `ndarray.setflags`.
+ The array flags cannot be set arbitrarily:
+ - UPDATEIFCOPY can only be set ``False``.
+ - WRITEBACKIFCOPY can only be set ``False``.
+ - ALIGNED can only be set ``True`` if the data is truly aligned.
+ - WRITEABLE can only be set ``True`` if the array owns its own memory
+ or the ultimate owner of the memory exposes a writeable buffer
+ interface or is a string.
+ Arrays can be both C-style and Fortran-style contiguous simultaneously.
+ This is clear for 1-dimensional arrays, but can also be true for higher
+ dimensional arrays.
+ Even for contiguous arrays a stride for a given dimension
+ ``arr.strides[dim]`` may be *arbitrary* if ``arr.shape[dim] == 1``
+ or the array has no elements.
+ It does *not* generally hold that ``self.strides[-1] == self.itemsize``
+ for C-style contiguous arrays or ``self.strides[0] == self.itemsize`` for
+ Fortran-style contiguous arrays is true.
+add_newdoc('numpy.core.multiarray', 'ndarray', ('flat',
+ A 1-D iterator over the array.
+ This is a `numpy.flatiter` instance, which acts similarly to, but is not
+ a subclass of, Python's built-in iterator object.
+ flatten : Return a copy of the array collapsed into one dimension.
+ flatiter
+ >>> x = np.arange(1, 7).reshape(2, 3)
+ [4, 5, 6]])
+ >>> x.flat[3]
+ >>> x.T
+ array([[1, 4],
+ [2, 5],
+ [3, 6]])
+ >>> x.T.flat[3]
+ >>> type(x.flat)
+ An assignment example:
+ >>> x.flat = 3; x
+ array([[3, 3, 3],
+ [3, 3, 3]])
+ >>> x.flat[[1,4]] = 1; x
+ array([[3, 1, 3],
+ [3, 1, 3]])
+add_newdoc('numpy.core.multiarray', 'ndarray', ('nbytes',
+ Total bytes consumed by the elements of the array.
+ Does not include memory consumed by non-element attributes of the
+ array object.
+ >>> x = np.zeros((3,5,2), dtype=np.complex128)
+ >>> x.nbytes
+ 480
+ >>> np.prod(x.shape) * x.itemsize
+add_newdoc('numpy.core.multiarray', 'ndarray', ('ndim',
+ Number of array dimensions.
+ >>> x.ndim
+ >>> y = np.zeros((2, 3, 4))
+ >>> y.ndim
+add_newdoc('numpy.core.multiarray', 'ndarray', ('real',
+ The real part of the array.
+ >>> x.real
+ array([ 1. , 0.70710678])
+ >>> x.real.dtype
+ numpy.real : equivalent function
+add_newdoc('numpy.core.multiarray', 'ndarray', ('shape',
+ Tuple of array dimensions.
+ The shape property is usually used to get the current shape of an array,
+ but may also be used to reshape the array in-place by assigning a tuple of
+ array dimensions to it. As with `numpy.reshape`, one of the new shape
+ dimensions can be -1, in which case its value is inferred from the size of
+ the array and the remaining dimensions. Reshaping an array in-place will
+ fail if a copy is required.
+ >>> x = np.array([1, 2, 3, 4])
+ >>> x.shape
+ (4,)
+ >>> y.shape
+ (2, 3, 4)
+ >>> y.shape = (3, 8)
+ >>> y
+ array([[ 0., 0., 0., 0., 0., 0., 0., 0.],
+ [ 0., 0., 0., 0., 0., 0., 0., 0.],
+ [ 0., 0., 0., 0., 0., 0., 0., 0.]])
+ >>> y.shape = (3, 6)
+ Traceback (most recent call last):
+ File "<stdin>", line 1, in <module>
+ ValueError: total size of new array must be unchanged
+ >>> np.zeros((4,2))[::2].shape = (-1,)
+ AttributeError: Incompatible shape for in-place modification. Use
+ `.reshape()` to make a copy with the desired shape.
+ numpy.reshape : similar function
+ ndarray.reshape : similar method
+add_newdoc('numpy.core.multiarray', 'ndarray', ('size',
+ Equal to ``np.prod(a.shape)``, i.e., the product of the array's
+ dimensions.
+ `a.size` returns a standard arbitrary precision Python integer. This
+ may not be the case with other methods of obtaining the same value
+ (like the suggested ``np.prod(a.shape)``, which returns an instance
+ of ``np.int_``), and may be relevant if the value is used further in
+ calculations that may overflow a fixed size integer type.
+ >>> x = np.zeros((3, 5, 2), dtype=np.complex128)
+ >>> x.size
+ >>> np.prod(x.shape)
+add_newdoc('numpy.core.multiarray', 'ndarray', ('strides',
+ Tuple of bytes to step in each dimension when traversing an array.
+ The byte offset of element ``(i[0], i[1], ..., i[n])`` in an array `a`
+ is::
+ offset = sum(np.array(i) * a.strides)
+ A more detailed explanation of strides can be found in the
+ "ndarray.rst" file in the NumPy reference guide.
+ Imagine an array of 32-bit integers (each 4 bytes)::
+ x = np.array([[0, 1, 2, 3, 4],
+ [5, 6, 7, 8, 9]], dtype=np.int32)
+ This array is stored in memory as 40 bytes, one after the other
+ (known as a contiguous block of memory). The strides of an array tell
+ us how many bytes we have to skip in memory to move to the next position
+ along a certain axis. For example, we have to skip 4 bytes (1 value) to
+ move to the next column, but 20 bytes (5 values) to get to the same
+ position in the next row. As such, the strides for the array `x` will be
+ ``(20, 4)``.
+ numpy.lib.stride_tricks.as_strided
+ >>> y = np.reshape(np.arange(2*3*4), (2,3,4))
+ array([[[ 0, 1, 2, 3],
+ [ 4, 5, 6, 7],
+ [ 8, 9, 10, 11]],
+ [[12, 13, 14, 15],
+ [16, 17, 18, 19],
+ [20, 21, 22, 23]]])
+ >>> y.strides
+ (48, 16, 4)
+ >>> y[1,1,1]
+ 17
+ >>> offset=sum(y.strides * np.array((1,1,1)))
+ >>> offset/y.itemsize
+ >>> x = np.reshape(np.arange(5*6*7*8), (5,6,7,8)).transpose(2,3,1,0)
+ >>> x.strides
+ (32, 4, 224, 1344)
+ >>> i = np.array([3,5,2,2])
+ >>> offset = sum(i * x.strides)
+ >>> x[3,5,2,2]
+ 813
+ >>> offset / x.itemsize
+add_newdoc('numpy.core.multiarray', 'ndarray', ('T',
+ The transposed array.
+ Same as ``self.transpose()``.
+ >>> x = np.array([[1.,2.],[3.,4.]])
+ array([[ 1., 2.],
+ [ 3., 4.]])
+ array([[ 1., 3.],
+ [ 2., 4.]])
+ >>> x = np.array([1.,2.,3.,4.])
+ array([ 1., 2., 3., 4.])
+ transpose
+# ndarray methods
+add_newdoc('numpy.core.multiarray', 'ndarray', ('__array__',
+ """ a.__array__([dtype], /) -> reference if type unchanged, copy otherwise.
+ Returns either a new reference to self if dtype is not given or a new array
+ of provided data type if dtype is different from the current dtype of the
+ array.
+add_newdoc('numpy.core.multiarray', 'ndarray', ('__array_prepare__',
+ """a.__array_prepare__(obj) -> Object of same type as ndarray object obj.
+add_newdoc('numpy.core.multiarray', 'ndarray', ('__array_wrap__',
+ """a.__array_wrap__(obj) -> Object of same type as ndarray object a.
+add_newdoc('numpy.core.multiarray', 'ndarray', ('__copy__',
+ """a.__copy__()
+ Used if :func:`copy.copy` is called on an array. Returns a copy of the array.
+ Equivalent to ``a.copy(order='K')``.
+add_newdoc('numpy.core.multiarray', 'ndarray', ('__deepcopy__',
+ """a.__deepcopy__(memo, /) -> Deep copy of array.
+ Used if :func:`copy.deepcopy` is called on an array.
+add_newdoc('numpy.core.multiarray', 'ndarray', ('__reduce__',
+ """a.__reduce__()
+ For pickling.
+add_newdoc('numpy.core.multiarray', 'ndarray', ('__setstate__',
+ """a.__setstate__(state, /)
+ For unpickling.
+ The `state` argument must be a sequence that contains the following
+ elements:
+ version : int
+ optional pickle version. If omitted defaults to 0.
+ shape : tuple
+ isFortran : bool
+ rawdata : string or list
+ a binary string with the data (or a list if 'a' is an object array)
+add_newdoc('numpy.core.multiarray', 'ndarray', ('all',
+ a.all(axis=None, out=None, keepdims=False, *, where=True)
+ Returns True if all elements evaluate to True.
+ Refer to `numpy.all` for full documentation.
+ numpy.all : equivalent function
+add_newdoc('numpy.core.multiarray', 'ndarray', ('any',
+ a.any(axis=None, out=None, keepdims=False, *, where=True)
+ Returns True if any of the elements of `a` evaluate to True.
+ Refer to `numpy.any` for full documentation.
+ numpy.any : equivalent function
+add_newdoc('numpy.core.multiarray', 'ndarray', ('argmax',
+ a.argmax(axis=None, out=None)
+ Return indices of the maximum values along the given axis.
+ Refer to `numpy.argmax` for full documentation.
+ numpy.argmax : equivalent function
+add_newdoc('numpy.core.multiarray', 'ndarray', ('argmin',
+ a.argmin(axis=None, out=None)
+ Return indices of the minimum values along the given axis.
+ Refer to `numpy.argmin` for detailed documentation.
+ numpy.argmin : equivalent function
+add_newdoc('numpy.core.multiarray', 'ndarray', ('argsort',
+ a.argsort(axis=-1, kind=None, order=None)
+ Returns the indices that would sort this array.
+ Refer to `numpy.argsort` for full documentation.
+ numpy.argsort : equivalent function
+add_newdoc('numpy.core.multiarray', 'ndarray', ('argpartition',
+ a.argpartition(kth, axis=-1, kind='introselect', order=None)
+ Returns the indices that would partition this array.
+ Refer to `numpy.argpartition` for full documentation.
+ .. versionadded:: 1.8.0
+ numpy.argpartition : equivalent function
+add_newdoc('numpy.core.multiarray', 'ndarray', ('astype',
+ a.astype(dtype, order='K', casting='unsafe', subok=True, copy=True)
+ Copy of the array, cast to a specified type.
+ dtype : str or dtype
+ Typecode or data-type to which the array is cast.
+ Controls the memory layout order of the result.
+ 'C' means C order, 'F' means Fortran order, 'A'
+ means 'F' order if all the arrays are Fortran contiguous,
+ 'C' order otherwise, and 'K' means as close to the
+ order the array elements appear in memory as possible.
+ Controls what kind of data casting may occur. Defaults to 'unsafe'
+ for backwards compatibility.
+ If True, then sub-classes will be passed-through (default), otherwise
+ the returned array will be forced to be a base-class array.
+ By default, astype always returns a newly allocated array. If this
+ is set to false, and the `dtype`, `order`, and `subok`
+ requirements are satisfied, the input array is returned instead
+ of a copy.
+ arr_t : ndarray
+ Unless `copy` is False and the other conditions for returning the input
+ array are satisfied (see description for `copy` input parameter), `arr_t`
+ is a new array of the same shape as the input array, with dtype, order
+ given by `dtype`, `order`.
+ Casting between a simple data type and a structured one is possible only
+ for "unsafe" casting. Casting to multiple fields is allowed, but
+ casting from multiple fields is not.
+ .. versionchanged:: 1.9.0
+ Casting from numeric to string types in 'safe' casting mode requires
+ that the string dtype length is long enough to store the max
+ integer/float value converted.
+ ComplexWarning
+ When casting from complex to float or int. To avoid this,
+ one should use ``a.real.astype(t)``.
+ >>> x = np.array([1, 2, 2.5])
+ array([1. , 2. , 2.5])
+ >>> x.astype(int)
+ array([1, 2, 2])
+add_newdoc('numpy.core.multiarray', 'ndarray', ('byteswap',
+ a.byteswap(inplace=False)
+ Swap the bytes of the array elements
+ Toggle between low-endian and big-endian data representation by
+ returning a byteswapped array, optionally swapped in-place.
+ Arrays of byte-strings are not swapped. The real and imaginary
+ parts of a complex number are swapped individually.
+ inplace : bool, optional
+ If ``True``, swap bytes in-place, default is ``False``.
+ The byteswapped array. If `inplace` is ``True``, this is
+ a view to self.
+ >>> A = np.array([1, 256, 8755], dtype=np.int16)
+ >>> list(map(hex, A))
+ ['0x1', '0x100', '0x2233']
+ >>> A.byteswap(inplace=True)
+ array([ 256, 1, 13090], dtype=int16)
+ ['0x100', '0x1', '0x3322']
+ Arrays of byte-strings are not swapped
+ >>> A = np.array([b'ceg', b'fac'])
+ >>> A.byteswap()
+ array([b'ceg', b'fac'], dtype='|S3')
+ ``A.newbyteorder().byteswap()`` produces an array with the same values
+ but different representation in memory
+ >>> A = np.array([1, 2, 3])
+ >>> A.view(np.uint8)
+ array([1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0,
+ 0, 0], dtype=uint8)
+ >>> A.newbyteorder().byteswap(inplace=True)
+ array([0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0,
+ 0, 3], dtype=uint8)
+add_newdoc('numpy.core.multiarray', 'ndarray', ('choose',
+ a.choose(choices, out=None, mode='raise')
+ Use an index array to construct a new array from a set of choices.
+ Refer to `numpy.choose` for full documentation.
+ numpy.choose : equivalent function
+add_newdoc('numpy.core.multiarray', 'ndarray', ('clip',
+ a.clip(min=None, max=None, out=None, **kwargs)
+ Return an array whose values are limited to ``[min, max]``.
+ One of max or min must be given.
+ Refer to `numpy.clip` for full documentation.
+ numpy.clip : equivalent function
+add_newdoc('numpy.core.multiarray', 'ndarray', ('compress',
+ a.compress(condition, axis=None, out=None)
+ Return selected slices of this array along given axis.
+ Refer to `numpy.compress` for full documentation.
+ numpy.compress : equivalent function
+add_newdoc('numpy.core.multiarray', 'ndarray', ('conj',
+ a.conj()
+ Complex-conjugate all elements.
+ Refer to `numpy.conjugate` for full documentation.
+ numpy.conjugate : equivalent function
+add_newdoc('numpy.core.multiarray', 'ndarray', ('conjugate',
+ a.conjugate()
+ Return the complex conjugate, element-wise.
+add_newdoc('numpy.core.multiarray', 'ndarray', ('copy',
+ a.copy(order='C')
+ Return a copy of the array.
+ Controls the memory layout of the copy. 'C' means C-order,
+ '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.)
+ numpy.copy
+ numpy.copyto
+ >>> x = np.array([[1,2,3],[4,5,6]], order='F')
+ >>> y = x.copy()
+ >>> x.fill(0)
+ array([[0, 0, 0],
+ [0, 0, 0]])
+ >>> y.flags['C_CONTIGUOUS']
+add_newdoc('numpy.core.multiarray', 'ndarray', ('cumprod',
+ a.cumprod(axis=None, dtype=None, out=None)
+ Return the cumulative product of the elements along the given axis.
+ Refer to `numpy.cumprod` for full documentation.
+ numpy.cumprod : equivalent function
+add_newdoc('numpy.core.multiarray', 'ndarray', ('cumsum',
+ a.cumsum(axis=None, dtype=None, out=None)
+ Return the cumulative sum of the elements along the given axis.
+ Refer to `numpy.cumsum` for full documentation.
+ numpy.cumsum : equivalent function
+add_newdoc('numpy.core.multiarray', 'ndarray', ('diagonal',
+ a.diagonal(offset=0, axis1=0, axis2=1)
+ Return specified diagonals. In NumPy 1.9 the returned array is a
+ read-only view instead of a copy as in previous NumPy versions. In
+ a future version the read-only restriction will be removed.
+ Refer to :func:`numpy.diagonal` for full documentation.
+ numpy.diagonal : equivalent function
+add_newdoc('numpy.core.multiarray', 'ndarray', ('dot',
+ a.dot(b, out=None)
+ Dot product of two arrays.
+ Refer to `numpy.dot` for full documentation.
+ numpy.dot : equivalent function
+ >>> 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', ('dump',
+ """a.dump(file)
+ Dump a pickle of the array to the specified file.
+ The array can be read back with pickle.load or numpy.load.
+ file : str or Path
+ A string naming the dump file.
+add_newdoc('numpy.core.multiarray', 'ndarray', ('dumps',
+ a.dumps()
+ Returns the pickle of the array as a string.
+ pickle.loads or numpy.loads will convert the string back to an array.
+add_newdoc('numpy.core.multiarray', 'ndarray', ('fill',
+ a.fill(value)
+ Fill the array with a scalar value.
+ value : scalar
+ All elements of `a` will be assigned this value.
+ >>> a = np.array([1, 2])
+ >>> a.fill(0)
+ array([0, 0])
+ >>> a = np.empty(2)
+ >>> a.fill(1)
+ array([1., 1.])
+add_newdoc('numpy.core.multiarray', 'ndarray', ('flatten',
+ a.flatten(order='C')
+ Return a copy of the array collapsed into one dimension.
+ 'C' means to flatten in row-major (C-style) order.
+ 'F' means to flatten in column-major (Fortran-
+ style) order. 'A' means to flatten in column-major
+ order if `a` is Fortran *contiguous* in memory,
+ row-major order otherwise. 'K' means to flatten
+ `a` in the order the elements occur in memory.
+ The default is 'C'.
+ y : ndarray
+ A copy of the input array, flattened to one dimension.
+ ravel : Return a flattened array.
+ flat : A 1-D flat iterator over the array.
+ >>> a = np.array([[1,2], [3,4]])
+ >>> a.flatten()
+ array([1, 2, 3, 4])
+ >>> a.flatten('F')
+ array([1, 3, 2, 4])
+add_newdoc('numpy.core.multiarray', 'ndarray', ('getfield',
+ a.getfield(dtype, offset=0)
+ Returns a field of the given array as a certain type.
+ A field is a view of the array data with a given data-type. The values in
+ the view are determined by the given type and the offset into the current
+ array in bytes. The offset needs to be such that the view dtype fits in the
+ array dtype; for example an array of dtype complex128 has 16-byte elements.
+ If taking a view with a 32-bit integer (4 bytes), the offset needs to be
+ between 0 and 12 bytes.
+ The data type of the view. The dtype size of the view can not be larger
+ than that of the array itself.
+ Number of bytes to skip before beginning the element view.
+ >>> x = np.diag([1.+1.j]*2)
+ >>> x[1, 1] = 2 + 4.j
+ array([[1.+1.j, 0.+0.j],
+ [0.+0.j, 2.+4.j]])
+ >>> x.getfield(np.float64)
+ array([[1., 0.],
+ [0., 2.]])
+ By choosing an offset of 8 bytes we can select the complex part of the
+ array for our view:
+ >>> x.getfield(np.float64, offset=8)
+ [0., 4.]])
+add_newdoc('numpy.core.multiarray', 'ndarray', ('item',
+ a.item(*args)
+ Copy an element of an array to a standard Python scalar and return it.
+ \\*args : Arguments (variable number and type)
+ * none: in this case, the method only works for arrays
+ with one element (`a.size == 1`), which element is
+ copied into a standard Python scalar object and returned.
+ * int_type: this argument is interpreted as a flat index into
+ the array, specifying which element to copy and return.
+ * tuple of int_types: functions as does a single int_type argument,
+ except that the argument is interpreted as an nd-index into the
+ z : Standard Python scalar object
+ A copy of the specified element of the array as a suitable
+ Python scalar
+ When the data type of `a` is longdouble or clongdouble, item() returns
+ a scalar array object because there is no available Python scalar that
+ would not lose information. Void arrays return a buffer object for item(),
+ unless fields are defined, in which case a tuple is returned.
+ `item` is very similar to a[args], except, instead of an array scalar,
+ a standard Python scalar is returned. This can be useful for speeding up
+ access to elements of the array and doing arithmetic on elements of the
+ array using Python's optimized math.
+ >>> np.random.seed(123)
+ >>> x = np.random.randint(9, size=(3, 3))
+ array([[2, 2, 6],
+ [1, 3, 6],
+ [1, 0, 1]])
+ >>> x.item(3)
+ >>> x.item(7)
+ >>> x.item((0, 1))
+ >>> x.item((2, 2))
+add_newdoc('numpy.core.multiarray', 'ndarray', ('itemset',
+ a.itemset(*args)
+ Insert scalar into an array (scalar is cast to array's dtype, if possible)
+ There must be at least 1 argument, and define the last argument
+ as *item*. Then, ``a.itemset(*args)`` is equivalent to but faster
+ than ``a[args] = item``. The item should be a scalar value and `args`
+ must select a single item in the array `a`.
+ \\*args : Arguments
+ If one argument: a scalar, only used in case `a` is of size 1.
+ If two arguments: the last argument is the value to be set
+ and must be a scalar, the first argument specifies a single array
+ element location. It is either an int or a tuple.
+ Compared to indexing syntax, `itemset` provides some speed increase
+ for placing a scalar into a particular location in an `ndarray`,
+ if you must do this. However, generally this is discouraged:
+ among other problems, it complicates the appearance of the code.
+ Also, when using `itemset` (and `item`) inside a loop, be sure
+ to assign the methods to a local variable to avoid the attribute
+ look-up at each loop iteration.
+ >>> x.itemset(4, 0)
+ >>> x.itemset((2, 2), 9)
+ [1, 0, 6],
+ [1, 0, 9]])
+add_newdoc('numpy.core.multiarray', 'ndarray', ('max',
+ a.max(axis=None, out=None, keepdims=False, initial=<no value>, where=True)
+ Return the maximum along a given axis.
+ Refer to `numpy.amax` for full documentation.
+ numpy.amax : equivalent function
+add_newdoc('numpy.core.multiarray', 'ndarray', ('mean',
+ a.mean(axis=None, dtype=None, out=None, keepdims=False, *, where=True)
+ Returns the average of the array elements along given axis.
+ Refer to `numpy.mean` for full documentation.
+ numpy.mean : equivalent function
+add_newdoc('numpy.core.multiarray', 'ndarray', ('min',
+ a.min(axis=None, out=None, keepdims=False, initial=<no value>, where=True)
+ Return the minimum along a given axis.
+ Refer to `numpy.amin` for full documentation.
+ numpy.amin : equivalent function
+add_newdoc('numpy.core.multiarray', 'ndarray', ('newbyteorder',
+ arr.newbyteorder(new_order='S', /)
+ Return the array with the same data viewed with a different byte order.
+ Equivalent to::
+ arr.view(arr.dtype.newbytorder(new_order))
+ Changes are also made in all fields and sub-arrays of the array data
+ type.
+ new_order : string, optional
+ Byte order to force; a value from the byte order specifications
+ below. `new_order` codes can be any of:
+ * 'S' - swap dtype from current to opposite endian
+ * {'<', 'little'} - little endian
+ * {'>', 'big'} - big endian
+ * '=' - native order, equivalent to `sys.byteorder`
+ * {'|', 'I'} - ignore (no change to byte order)
+ The default value ('S') results in swapping the current
+ byte order.
+ new_arr : array
+ New array object with the dtype reflecting given change to the
+add_newdoc('numpy.core.multiarray', 'ndarray', ('nonzero',
+ a.nonzero()
+ Return the indices of the elements that are non-zero.
+ Refer to `numpy.nonzero` for full documentation.
+ numpy.nonzero : equivalent function
+add_newdoc('numpy.core.multiarray', 'ndarray', ('prod',
+ a.prod(axis=None, dtype=None, out=None, keepdims=False, initial=1, where=True)
+ Return the product of the array elements over the given axis
+ Refer to `numpy.prod` for full documentation.
+ numpy.prod : equivalent function
+add_newdoc('numpy.core.multiarray', 'ndarray', ('ptp',
+ a.ptp(axis=None, out=None, keepdims=False)
+ Peak to peak (maximum - minimum) value along a given axis.
+ Refer to `numpy.ptp` for full documentation.
+ numpy.ptp : equivalent function
+add_newdoc('numpy.core.multiarray', 'ndarray', ('put',
+ a.put(indices, values, mode='raise')
+ Set ``a.flat[n] = values[n]`` for all `n` in indices.
+ Refer to `numpy.put` for full documentation.
+ numpy.put : equivalent function
+add_newdoc('numpy.core.multiarray', 'ndarray', ('ravel',
+ a.ravel([order])
+ Return a flattened array.
+ Refer to `numpy.ravel` for full documentation.
+ numpy.ravel : equivalent function
+ ndarray.flat : a flat iterator on the array.
+add_newdoc('numpy.core.multiarray', 'ndarray', ('repeat',
+ a.repeat(repeats, axis=None)
+ Repeat elements of an array.
+ Refer to `numpy.repeat` for full documentation.
+ numpy.repeat : equivalent function
+add_newdoc('numpy.core.multiarray', 'ndarray', ('reshape',
+ a.reshape(shape, order='C')
+ Returns an array containing the same data with a new shape.
+ Refer to `numpy.reshape` for full documentation.
+ numpy.reshape : equivalent function
+ Unlike the free function `numpy.reshape`, this method on `ndarray` allows
+ the elements of the shape parameter to be passed in as separate arguments.
+ For example, ``a.reshape(10, 11)`` is equivalent to
+ ``a.reshape((10, 11))``.
+add_newdoc('numpy.core.multiarray', 'ndarray', ('resize',
+ a.resize(new_shape, refcheck=True)
+ Change shape and size of array in-place.
+ new_shape : tuple of ints, or `n` ints
+ Shape of resized array.
+ refcheck : bool, optional
+ If False, reference count will not be checked. Default is True.
+ If `a` does not own its own data or references or views to it exist,
+ and the data memory must be changed.
+ PyPy only: will always raise if the data memory must be changed, since
+ there is no reliable way to determine if references or views to it
+ exist.
+ SystemError
+ If the `order` keyword argument is specified. This behaviour is a
+ bug in NumPy.
+ resize : Return a new array with the specified shape.
+ This reallocates space for the data area if necessary.
+ Only contiguous arrays (data elements consecutive in memory) can be
+ resized.
+ The purpose of the reference count check is to make sure you
+ do not use this array as a buffer for another Python object and then
+ reallocate the memory. However, reference counts can increase in
+ other ways so if you are sure that you have not shared the memory
+ for this array with another Python object, then you may safely set
+ `refcheck` to False.
+ Shrinking an array: array is flattened (in the order that the data are
+ stored in memory), resized, and reshaped:
+ >>> a = np.array([[0, 1], [2, 3]], order='C')
+ >>> a.resize((2, 1))
+ array([[0],
+ [1]])
+ >>> a = np.array([[0, 1], [2, 3]], order='F')
+ [2]])
+ Enlarging an array: as above, but missing entries are filled with zeros:
+ >>> b = np.array([[0, 1], [2, 3]])
+ >>> b.resize(2, 3) # new_shape parameter doesn't have to be a tuple
+ >>> b
+ [3, 0, 0]])
+ Referencing an array prevents resizing...
+ >>> c = a
+ >>> a.resize((1, 1))
+ ValueError: cannot resize an array that references or is referenced ...
+ Unless `refcheck` is False:
+ >>> a.resize((1, 1), refcheck=False)
+ array([[0]])
+ >>> c
+add_newdoc('numpy.core.multiarray', 'ndarray', ('round',
+ a.round(decimals=0, out=None)
+ Return `a` with each element rounded to the given number of decimals.
+ Refer to `numpy.around` for full documentation.
+ numpy.around : equivalent function
+add_newdoc('numpy.core.multiarray', 'ndarray', ('searchsorted',
+ a.searchsorted(v, side='left', sorter=None)
+ Find indices where elements of v should be inserted in a to maintain order.
+ For full documentation, see `numpy.searchsorted`
+ numpy.searchsorted : equivalent function
+add_newdoc('numpy.core.multiarray', 'ndarray', ('setfield',
+ a.setfield(val, dtype, offset=0)
+ Put a value into a specified place in a field defined by a data-type.
+ Place `val` into `a`'s field defined by `dtype` and beginning `offset`
+ bytes into the field.
+ val : object
+ Value to be placed in field.
+ Data-type of the field in which to place `val`.
+ The number of bytes into the field at which to place `val`.
+ getfield
+ >>> x = np.eye(3)
+ array([[1., 0., 0.],
+ [0., 1., 0.],
+ [0., 0., 1.]])
+ >>> x.setfield(3, np.int32)
+ >>> x.getfield(np.int32)
+ [3, 3, 3],
+ [3, 3, 3]], dtype=int32)
+ array([[1.0e+000, 1.5e-323, 1.5e-323],
+ [1.5e-323, 1.0e+000, 1.5e-323],
+ [1.5e-323, 1.5e-323, 1.0e+000]])
+ >>> x.setfield(np.eye(3), np.int32)
+add_newdoc('numpy.core.multiarray', 'ndarray', ('setflags',
+ a.setflags(write=None, align=None, uic=None)
+ Set array flags WRITEABLE, ALIGNED, (WRITEBACKIFCOPY and UPDATEIFCOPY),
+ respectively.
+ These Boolean-valued flags affect how numpy interprets the memory
+ area used by `a` (see Notes below). The ALIGNED flag can only
+ be set to True if the data is actually aligned according to the type.
+ The WRITEBACKIFCOPY and (deprecated) UPDATEIFCOPY flags can never be set
+ to True. The flag WRITEABLE can only be set to True if the array owns its
+ own memory, or the ultimate owner of the memory exposes a writeable buffer
+ interface, or is a string. (The exception for string is made so that
+ unpickling can be done without copying memory.)
+ write : bool, optional
+ Describes whether or not `a` can be written to.
+ align : bool, optional
+ Describes whether or not `a` is aligned properly for its type.
+ uic : bool, optional
+ Describes whether or not `a` is a copy of another "base" array.
+ Array flags provide information about how the memory area used
+ for the array is to be interpreted. There are 7 Boolean flags
+ in use, only four of which can be changed by the user:
+ WRITEBACKIFCOPY, UPDATEIFCOPY, WRITEABLE, and ALIGNED.
+ WRITEABLE (W) the data area can be written to;
+ ALIGNED (A) the data and strides are aligned appropriately for the hardware
+ (as determined by the compiler);
+ UPDATEIFCOPY (U) (deprecated), replaced by WRITEBACKIFCOPY;
+ WRITEBACKIFCOPY (X) this array is a copy of some other array (referenced
+ by .base). When the C-API function PyArray_ResolveWritebackIfCopy is
+ called, the base array will be updated with the contents of this array.
+ All flags can be accessed using the single (upper case) letter as well
+ as the full name.
+ >>> y = np.array([[3, 1, 7],
+ ... [2, 0, 0],
+ ... [8, 5, 9]])
+ array([[3, 1, 7],
+ [2, 0, 0],
+ [8, 5, 9]])
+ >>> y.flags
+ C_CONTIGUOUS : True
+ F_CONTIGUOUS : False
+ OWNDATA : True
+ WRITEABLE : True
+ ALIGNED : True
+ WRITEBACKIFCOPY : False
+ UPDATEIFCOPY : False
+ >>> y.setflags(write=0, align=0)
+ WRITEABLE : False
+ ALIGNED : False
+ >>> y.setflags(uic=1)
+ ValueError: cannot set WRITEBACKIFCOPY flag to True
+add_newdoc('numpy.core.multiarray', 'ndarray', ('sort',
+ a.sort(axis=-1, kind=None, order=None)
+ Sort an array in-place. Refer to `numpy.sort` for full documentation.
+ axis : int, optional
+ Axis along which to sort. Default is -1, which means sort along the
+ last axis.
+ kind : {'quicksort', 'mergesort', 'heapsort', 'stable'}, optional
+ Sorting algorithm. The default is 'quicksort'. Note that both 'stable'
+ and 'mergesort' use timsort under the covers and, in general, the
+ actual implementation will vary with datatype. The 'mergesort' option
+ is retained for backwards compatibility.
+ .. versionchanged:: 1.15.0.
+ The 'stable' option was added.
+ order : str or list of str, optional
+ When `a` is an array with fields defined, this argument specifies
+ which fields to compare first, second, etc. A single field can
+ be specified as a string, and not all fields need be specified,
+ but unspecified fields will still be used, in the order in which
+ they come up in the dtype, to break ties.
+ numpy.sort : Return a sorted copy of an array.
+ numpy.argsort : Indirect sort.
+ numpy.lexsort : Indirect stable sort on multiple keys.
+ numpy.searchsorted : Find elements in sorted array.
+ numpy.partition: Partial sort.
+ See `numpy.sort` for notes on the different sorting algorithms.
+ >>> a = np.array([[1,4], [3,1]])
+ >>> a.sort(axis=1)
+ [1, 3]])
+ >>> a.sort(axis=0)
+ array([[1, 3],
+ [1, 4]])
+ Use the `order` keyword to specify a field to use when sorting a
+ structured array:
+ >>> a = np.array([('a', 2), ('c', 1)], dtype=[('x', 'S1'), ('y', int)])
+ >>> a.sort(order='y')
+ array([(b'c', 1), (b'a', 2)],
+ dtype=[('x', 'S1'), ('y', '<i8')])
+add_newdoc('numpy.core.multiarray', 'ndarray', ('partition',
+ a.partition(kth, axis=-1, kind='introselect', order=None)
+ Rearranges the elements in the array in such a way that the value of the
+ element in kth position is in the position it would be in a sorted array.
+ All elements smaller than the kth element are moved before this element and
+ all equal or greater are moved behind it. The ordering of the elements in
+ the two partitions is undefined.
+ kth : int or sequence of ints
+ Element index to partition by. The kth element value will be in its
+ final sorted position and all smaller elements will be moved before it
+ and all equal or greater elements behind it.
+ The order of all elements in the partitions is undefined.
+ If provided with a sequence of kth it will partition all elements
+ indexed by kth of them into their sorted position at once.
+ kind : {'introselect'}, optional
+ Selection algorithm. Default is 'introselect'.
+ be specified as a string, and not all fields need to be specified,
+ numpy.partition : Return a parititioned copy of an array.
+ argpartition : Indirect partition.
+ sort : Full sort.
+ See ``np.partition`` for notes on the different algorithms.
+ >>> a = np.array([3, 4, 2, 1])
+ >>> a.partition(3)
+ array([2, 1, 3, 4])
+ >>> a.partition((1, 3))
+add_newdoc('numpy.core.multiarray', 'ndarray', ('squeeze',
+ a.squeeze(axis=None)
+ Remove axes of length one from `a`.
+ Refer to `numpy.squeeze` for full documentation.
+ numpy.squeeze : equivalent function
+add_newdoc('numpy.core.multiarray', 'ndarray', ('std',
+ 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.
+ Refer to `numpy.std` for full documentation.
+ numpy.std : equivalent function
+add_newdoc('numpy.core.multiarray', 'ndarray', ('sum',
+ a.sum(axis=None, dtype=None, out=None, keepdims=False, initial=0, where=True)
+ Return the sum of the array elements over the given axis.
+ Refer to `numpy.sum` for full documentation.
+ numpy.sum : equivalent function
+add_newdoc('numpy.core.multiarray', 'ndarray', ('swapaxes',
+ a.swapaxes(axis1, axis2)
+ Return a view of the array with `axis1` and `axis2` interchanged.
+ Refer to `numpy.swapaxes` for full documentation.
+ numpy.swapaxes : equivalent function
+add_newdoc('numpy.core.multiarray', 'ndarray', ('take',
+ a.take(indices, axis=None, out=None, mode='raise')
+ Return an array formed from the elements of `a` at the given indices.
+ Refer to `numpy.take` for full documentation.
+ numpy.take : equivalent function
+add_newdoc('numpy.core.multiarray', 'ndarray', ('tofile',
+ a.tofile(fid, sep="", format="%s")
+ Write array to a file as text or binary (default).
+ Data is always written in 'C' order, independent of the order of `a`.
+ The data produced by this method can be recovered using the function
+ fromfile().
+ fid : file or str or Path
+ An open file object, or a string containing a filename.
+ Separator between array items for text output.
+ If "" (empty), a binary file is written, equivalent to
+ ``file.write(a.tobytes())``.
+ format : str
+ Format string for text file output.
+ Each entry in the array is formatted to text by first converting
+ it to the closest Python type, and then using "format" % item.
+ This is a convenience function for quick storage of array data.
+ Information on endianness and precision is lost, so this method is not a
+ good choice for files intended to archive data or transport data between
+ machines with different endianness. Some of these problems can be overcome
+ by outputting the data as text files, at the expense of speed and file
+ size.
+ When fid is a file object, array contents are directly written to the
+ file, bypassing the file object's ``write`` method. As a result, tofile
+ cannot be used with files objects supporting compression (e.g., GzipFile)
+ or file-like objects that do not support ``fileno()`` (e.g., BytesIO).
+add_newdoc('numpy.core.multiarray', 'ndarray', ('tolist',
+ a.tolist()
+ Return the array as an ``a.ndim``-levels deep nested list of Python scalars.
+ Return a copy of the array data as a (nested) Python list.
+ Data items are converted to the nearest compatible builtin Python type, via
+ the `~numpy.ndarray.item` function.
+ If ``a.ndim`` is 0, then since the depth of the nested list is 0, it will
+ not be a list at all, but a simple Python scalar.
+ none
+ y : object, or list of object, or list of list of object, or ...
+ The possibly nested list of array elements.
+ The array may be recreated via ``a = np.array(a.tolist())``, although this
+ may sometimes lose precision.
+ For a 1D array, ``a.tolist()`` is almost the same as ``list(a)``,
+ except that ``tolist`` changes numpy scalars to Python scalars:
+ >>> a = np.uint32([1, 2])
+ >>> a_list = list(a)
+ >>> a_list
+ [1, 2]
+ >>> type(a_list[0])
+ <class 'numpy.uint32'>
+ >>> a_tolist = a.tolist()
+ >>> a_tolist
+ >>> type(a_tolist[0])
+ <class 'int'>
+ Additionally, for a 2D array, ``tolist`` applies recursively:
+ >>> a = np.array([[1, 2], [3, 4]])
+ >>> list(a)
+ [array([1, 2]), array([3, 4])]
+ >>> a.tolist()
+ [[1, 2], [3, 4]]
+ The base case for this recursion is a 0D array:
+ >>> a = np.array(1)
+ TypeError: iteration over a 0-d array
+add_newdoc('numpy.core.multiarray', 'ndarray', ('tobytes', """
+ a.tobytes(order='C')
+ Construct Python bytes containing the raw data bytes in the array.
+ Constructs Python bytes showing a copy of the raw contents of
+ data memory. The bytes object is produced in C-order by default.
+ This behavior is controlled by the ``order`` parameter.
+ .. versionadded:: 1.9.0
+ order : {'C', 'F', 'A'}, optional
+ Controls the memory layout of the bytes object. 'C' means C-order,
+ 'F' means F-order, 'A' (short for *Any*) means 'F' if `a` is
+ Fortran contiguous, 'C' otherwise. Default is 'C'.
+ s : bytes
+ Python bytes exhibiting a copy of `a`'s raw data.
+ >>> x = np.array([[0, 1], [2, 3]], dtype='<u2')
+ >>> x.tobytes()
+ b'\\x00\\x00\\x01\\x00\\x02\\x00\\x03\\x00'
+ >>> x.tobytes('C') == x.tobytes()
+ >>> x.tobytes('F')
+ b'\\x00\\x00\\x02\\x00\\x01\\x00\\x03\\x00'
+add_newdoc('numpy.core.multiarray', 'ndarray', ('tostring', r"""
+ a.tostring(order='C')
+ A compatibility alias for `tobytes`, with exactly the same behavior.
+ Despite its name, it returns `bytes` not `str`\ s.
+ .. deprecated:: 1.19.0
+add_newdoc('numpy.core.multiarray', 'ndarray', ('trace',
+ a.trace(offset=0, axis1=0, axis2=1, dtype=None, out=None)
+ Return the sum along diagonals of the array.
+ Refer to `numpy.trace` for full documentation.
+ numpy.trace : equivalent function
+add_newdoc('numpy.core.multiarray', 'ndarray', ('transpose',
+ a.transpose(*axes)
+ Returns a view of the array with axes transposed.
+ For a 1-D array this has no effect, as a transposed vector is simply the
+ same vector. To convert a 1-D array into a 2D column vector, an additional
+ dimension must be added. `np.atleast2d(a).T` achieves this, as does
+ `a[:, np.newaxis]`.
+ For a 2-D array, this is a standard matrix transpose.
+ For an n-D array, if axes are given, their order indicates how the
+ axes are permuted (see Examples). If axes are not provided and
+ ``a.shape = (i[0], i[1], ... i[n-2], i[n-1])``, then
+ ``a.transpose().shape = (i[n-1], i[n-2], ... i[1], i[0])``.
+ axes : None, tuple of ints, or `n` ints
+ * None or no argument: reverses the order of the axes.
+ * tuple of ints: `i` in the `j`-th place in the tuple means `a`'s
+ `i`-th axis becomes `a.transpose()`'s `j`-th axis.
+ * `n` ints: same as an n-tuple of the same ints (this form is
+ intended simply as a "convenience" alternative to the tuple form)
+ View of `a`, with axes suitably permuted.
+ ndarray.T : Array property returning the array transposed.
+ ndarray.reshape : Give a new shape to an array without changing its data.
+ >>> a.transpose()
+ [2, 4]])
+ >>> a.transpose((1, 0))
+ >>> a.transpose(1, 0)
+add_newdoc('numpy.core.multiarray', 'ndarray', ('var',
+ a.var(axis=None, dtype=None, out=None, ddof=0, keepdims=False, *, where=True)
+ Returns the variance of the array elements, along given axis.
+ Refer to `numpy.var` for full documentation.
+ numpy.var : equivalent function
+add_newdoc('numpy.core.multiarray', 'ndarray', ('view',
+ a.view([dtype][, type])
+ New view of array with the same data.
+ .. note::
+ Passing None for ``dtype`` is different from omitting the parameter,
+ since the former invokes ``dtype(None)`` which is an alias for
+ ``dtype('float_')``.
+ dtype : data-type or ndarray sub-class, optional
+ Data-type descriptor of the returned view, e.g., float32 or int16.
+ Omitting it results in the view having the same data-type as `a`.
+ This argument can also be specified as an ndarray sub-class, which
+ then specifies the type of the returned object (this is equivalent to
+ setting the ``type`` parameter).
+ type : Python type, optional
+ Type of the returned view, e.g., ndarray or matrix. Again, omission
+ of the parameter results in type preservation.
+ ``a.view()`` is used two different ways:
+ ``a.view(some_dtype)`` or ``a.view(dtype=some_dtype)`` constructs a view
+ of the array's memory with a different data-type. This can cause a
+ reinterpretation of the bytes of memory.
+ ``a.view(ndarray_subclass)`` or ``a.view(type=ndarray_subclass)`` just
+ returns an instance of `ndarray_subclass` that looks at the same array
+ (same shape, dtype, etc.) This does not cause a reinterpretation of the
+ For ``a.view(some_dtype)``, if ``some_dtype`` has a different number of
+ bytes per entry than the previous dtype (for example, converting a
+ regular array to a structured array), then the behavior of the view
+ cannot be predicted just from the superficial appearance of ``a`` (shown
+ by ``print(a)``). It also depends on exactly how ``a`` is stored in
+ memory. Therefore if ``a`` is C-ordered versus fortran-ordered, versus
+ defined as a slice or transpose, etc., the view may give different
+ results.
+ >>> x = np.array([(1, 2)], dtype=[('a', np.int8), ('b', np.int8)])
+ Viewing array data using a different type and dtype:
+ >>> y = x.view(dtype=np.int16, type=np.matrix)
+ matrix([[513]], dtype=int16)
+ >>> print(type(y))
+ <class 'numpy.matrix'>
+ Creating a view on a structured array so it can be used in calculations
+ >>> x = np.array([(1, 2),(3,4)], dtype=[('a', np.int8), ('b', np.int8)])
+ >>> xv = x.view(dtype=np.int8).reshape(-1,2)
+ >>> xv
+ [3, 4]], dtype=int8)
+ >>> xv.mean(0)
+ array([2., 3.])
+ Making changes to the view changes the underlying array
+ >>> xv[0,1] = 20
+ array([(1, 20), (3, 4)], dtype=[('a', 'i1'), ('b', 'i1')])
+ Using a view to convert an array to a recarray:
+ >>> z = x.view(np.recarray)
+ >>> z.a
+ array([1, 3], dtype=int8)
+ Views share data:
+ >>> x[0] = (9, 10)
+ >>> z[0]
+ (9, 10)
+ Views that change the dtype size (bytes per entry) should normally be
+ avoided on arrays defined by slices, transposes, fortran-ordering, etc.:
+ >>> x = np.array([[1,2,3],[4,5,6]], dtype=np.int16)
+ >>> y = x[:, 0:2]
+ [4, 5]], dtype=int16)
+ >>> y.view(dtype=[('width', np.int16), ('length', np.int16)])
+ ValueError: To change to a dtype of a different size, the array must be C-contiguous
+ >>> z = y.copy()
+ >>> z.view(dtype=[('width', np.int16), ('length', np.int16)])
+ array([[(1, 2)],
+ [(4, 5)]], dtype=[('width', '<i2'), ('length', '<i2')])
+# umath functions
+add_newdoc('numpy.core.umath', 'frompyfunc',
+ frompyfunc(func, nin, nout, *[, identity])
+ Takes an arbitrary Python function and returns a NumPy ufunc.
+ Can be used, for example, to add broadcasting to a built-in Python
+ function (see Examples section).
+ func : Python function object
+ An arbitrary Python function.
+ nin : int
+ The number of input arguments.
+ nout : int
+ The number of objects returned by `func`.
+ identity : object, optional
+ The value to use for the `~numpy.ufunc.identity` attribute of the resulting
+ object. If specified, this is equivalent to setting the underlying
+ C ``identity`` field to ``PyUFunc_IdentityValue``.
+ If omitted, the identity is set to ``PyUFunc_None``. Note that this is
+ _not_ equivalent to setting the identity to ``None``, which implies the
+ operation is reorderable.
+ out : ufunc
+ Returns a NumPy universal function (``ufunc``) object.
+ vectorize : Evaluates pyfunc over input arrays using broadcasting rules of numpy.
+ The returned ufunc always returns PyObject arrays.
+ Use frompyfunc to add broadcasting to the Python function ``oct``:
+ >>> oct_array = np.frompyfunc(oct, 1, 1)
+ >>> oct_array(np.array((10, 30, 100)))
+ array(['0o12', '0o36', '0o144'], dtype=object)
+ >>> np.array((oct(10), oct(30), oct(100))) # for comparison
+ array(['0o12', '0o36', '0o144'], dtype='<U5')
+add_newdoc('numpy.core.umath', 'geterrobj',
+ geterrobj()
+ Return the current object that defines floating-point error handling.
+ The error object contains all information that defines the error handling
+ behavior in NumPy. `geterrobj` is used internally by the other
+ functions that get and set error handling behavior (`geterr`, `seterr`,
+ `geterrcall`, `seterrcall`).
+ errobj : list
+ The error object, a list containing three elements:
+ [internal numpy buffer size, error mask, error callback function].
+ The error mask is a single integer that holds the treatment information
+ on all four floating point errors. The information for each error type
+ is contained in three bits of the integer. If we print it in base 8, we
+ can see what treatment is set for "invalid", "under", "over", and
+ "divide" (in that order). The printed string can be interpreted with
+ * 0 : 'ignore'
+ * 1 : 'warn'
+ * 2 : 'raise'
+ * 3 : 'call'
+ * 4 : 'print'
+ * 5 : 'log'
+ seterrobj, seterr, geterr, seterrcall, geterrcall
+ getbufsize, setbufsize
+ For complete documentation of the types of floating-point exceptions and
+ treatment options, see `seterr`.
+ >>> np.geterrobj() # first get the defaults
+ [8192, 521, None]
+ >>> def err_handler(type, flag):
+ ... print("Floating point error (%s), with flag %s" % (type, flag))
+ >>> old_bufsize = np.setbufsize(20000)
+ >>> old_err = np.seterr(divide='raise')
+ >>> old_handler = np.seterrcall(err_handler)
+ >>> np.geterrobj()
+ [8192, 521, <function err_handler at 0x91dcaac>]
+ >>> old_err = np.seterr(all='ignore')
+ >>> np.base_repr(np.geterrobj()[1], 8)
+ '0'
+ >>> old_err = np.seterr(divide='warn', over='log', under='call',
+ ... invalid='print')
+ '4351'
+add_newdoc('numpy.core.umath', 'seterrobj',
+ seterrobj(errobj)
+ Set the object that defines floating-point error handling.
+ behavior in NumPy. `seterrobj` is used internally by the other
+ functions that set error handling behavior (`seterr`, `seterrcall`).
+ geterrobj, seterr, geterr, seterrcall, geterrcall
+ >>> old_errobj = np.geterrobj() # first get the defaults
+ >>> old_errobj
+ >>> new_errobj = [20000, 12, err_handler]
+ >>> np.seterrobj(new_errobj)
+ >>> np.base_repr(12, 8) # int for divide=4 ('print') and over=1 ('warn')
+ '14'
+ >>> np.geterr()
+ {'over': 'warn', 'divide': 'print', 'invalid': 'ignore', 'under': 'ignore'}
+ >>> np.geterrcall() is err_handler
+# compiled_base functions
+add_newdoc('numpy.core.multiarray', 'add_docstring',
+ add_docstring(obj, docstring)
+ Add a docstring to a built-in obj if possible.
+ If the obj already has a docstring raise a RuntimeError
+ If this routine does not know how to add a docstring to the object
+ raise a TypeError
+add_newdoc('numpy.core.umath', '_add_newdoc_ufunc',
+ add_ufunc_docstring(ufunc, new_docstring)
+ Replace the docstring for a ufunc with new_docstring.
+ This method will only work if the current docstring for
+ the ufunc is NULL. (At the C level, i.e. when ufunc->doc is NULL.)
+ ufunc : numpy.ufunc
+ A ufunc whose current doc is NULL.
+ new_docstring : string
+ The new docstring for the ufunc.
+ This method allocates memory for new_docstring on
+ the heap. Technically this creates a mempory leak, since this
+ memory will not be reclaimed until the end of the program
+ even if the ufunc itself is removed. However this will only
+ be a problem if the user is repeatedly creating ufuncs with
+ no documentation, adding documentation via add_newdoc_ufunc,
+ and then throwing away the ufunc.
+add_newdoc('numpy.core.multiarray', '_set_madvise_hugepage',
+ _set_madvise_hugepage(enabled: bool) -> bool
+ Set or unset use of ``madvise (2)`` MADV_HUGEPAGE support when
+ allocating the array data. Returns the previously set value.
+ See `global_state` for more information.
+add_newdoc('numpy.core._multiarray_tests', 'format_float_OSprintf_g',
+ format_float_OSprintf_g(val, precision)
+ Print a floating point scalar using the system's printf function,
+ equivalent to:
+ printf("%.*g", precision, val);
+ for half/float/double, or replacing 'g' by 'Lg' for longdouble. This
+ method is designed to help cross-validate the format_float_* methods.
+ val : python float or numpy floating scalar
+ Value to format.
+ precision : non-negative integer, optional
+ Precision given to printf.
+ rep : string
+ The string representation of the floating point value
+ format_float_scientific
+ format_float_positional
+# Documentation for ufunc attributes and methods
+# ufunc object
+add_newdoc('numpy.core', 'ufunc',
+ Functions that operate element by element on whole arrays.
+ To see the documentation for a specific ufunc, use `info`. For
+ example, ``np.info(np.sin)``. Because ufuncs are written in C
+ (for speed) and linked into Python with NumPy's ufunc facility,
+ Python's help() function finds this page whenever help() is called
+ on a ufunc.
+ A detailed explanation of ufuncs can be found in the docs for :ref:`ufuncs`.
+ **Calling ufuncs:** ``op(*x[, out], where=True, **kwargs)``
+ Apply `op` to the arguments `*x` elementwise, broadcasting the arguments.
+ The broadcasting rules are:
+ * Dimensions of length 1 may be prepended to either array.
+ * Arrays may be repeated along dimensions of length 1.
+ *x : array_like
+ Input arrays.
+ out : ndarray, None, or tuple of ndarray and None, optional
+ Alternate array object(s) in which to put the result; if provided, it
+ must have a shape that the inputs broadcast to. A tuple of arrays
+ (possible only as a keyword argument) must have length equal to the
+ number of outputs; use None for uninitialized outputs to be
+ allocated by the ufunc.
+ where : array_like, optional
+ This condition is broadcast over the input. At locations where the
+ condition is True, the `out` array will be set to the ufunc result.
+ Elsewhere, the `out` array will retain its original value.
+ Note that if an uninitialized `out` array is created via the default
+ ``out=None``, locations within it where the condition is False will
+ remain uninitialized.
+ **kwargs
+ For other keyword-only arguments, see the :ref:`ufunc docs <ufuncs.kwargs>`.
+ r : ndarray or tuple of ndarray
+ `r` will have the shape that the arrays in `x` broadcast to; if `out` is
+ provided, it will be returned. If not, `r` will be allocated and
+ may contain uninitialized values. If the function has more than one
+ output, then the result will be a tuple of arrays.
+# ufunc attributes
+add_newdoc('numpy.core', 'ufunc', ('identity',
+ The identity value.
+ Data attribute containing the identity element for the ufunc, if it has one.
+ If it does not, the attribute value is None.
+ >>> np.add.identity
+ >>> np.multiply.identity
+ >>> np.power.identity
+ >>> print(np.exp.identity)
+add_newdoc('numpy.core', 'ufunc', ('nargs',
+ The number of arguments.
+ Data attribute containing the number of arguments the ufunc takes, including
+ optional ones.
+ Typically this value will be one more than what you might expect because all
+ ufuncs take the optional "out" argument.
+ >>> np.add.nargs
+ >>> np.multiply.nargs
+ >>> np.power.nargs
+ >>> np.exp.nargs
+add_newdoc('numpy.core', 'ufunc', ('nin',
+ The number of inputs.
+ Data attribute containing the number of arguments the ufunc treats as input.
+ >>> np.add.nin
+ >>> np.multiply.nin
+ >>> np.power.nin
+ >>> np.exp.nin
+add_newdoc('numpy.core', 'ufunc', ('nout',
+ The number of outputs.
+ Data attribute containing the number of arguments the ufunc treats as output.
+ Since all ufuncs can take output arguments, this will always be (at least) 1.
+ >>> np.add.nout
+ >>> np.multiply.nout
+ >>> np.power.nout
+ >>> np.exp.nout
+add_newdoc('numpy.core', 'ufunc', ('ntypes',
+ The number of types.
+ The number of numerical NumPy types - of which there are 18 total - on which
+ the ufunc can operate.
+ numpy.ufunc.types
+ >>> np.add.ntypes
+ 18
+ >>> np.multiply.ntypes
+ >>> np.power.ntypes
+ >>> np.exp.ntypes
+ 7
+ >>> np.remainder.ntypes
+ 14
+add_newdoc('numpy.core', 'ufunc', ('types',
+ Returns a list with types grouped input->output.
+ Data attribute listing the data-type "Domain-Range" groupings the ufunc can
+ deliver. The data-types are given using the character codes.
+ numpy.ufunc.ntypes
+ >>> np.add.types
+ ['??->?', 'bb->b', 'BB->B', 'hh->h', 'HH->H', 'ii->i', 'II->I', 'll->l',
+ 'LL->L', 'qq->q', 'QQ->Q', 'ff->f', 'dd->d', 'gg->g', 'FF->F', 'DD->D',
+ 'GG->G', 'OO->O']
+ >>> np.multiply.types
+ >>> np.power.types
+ ['bb->b', 'BB->B', 'hh->h', 'HH->H', 'ii->i', 'II->I', 'll->l', 'LL->L',
+ 'qq->q', 'QQ->Q', 'ff->f', 'dd->d', 'gg->g', 'FF->F', 'DD->D', 'GG->G',
+ 'OO->O']
+ >>> np.exp.types
+ ['f->f', 'd->d', 'g->g', 'F->F', 'D->D', 'G->G', 'O->O']
+ >>> np.remainder.types
+ 'qq->q', 'QQ->Q', 'ff->f', 'dd->d', 'gg->g', 'OO->O']
+add_newdoc('numpy.core', 'ufunc', ('signature',
+ Definition of the core elements a generalized ufunc operates on.
+ The signature determines how the dimensions of each input/output array
+ are split into core and loop dimensions:
+ 1. Each dimension in the signature is matched to a dimension of the
+ corresponding passed-in array, starting from the end of the shape tuple.
+ 2. Core dimensions assigned to the same label in the signature must have
+ exactly matching sizes, no broadcasting is performed.
+ 3. The core dimensions are removed from all inputs and the remaining
+ dimensions are broadcast together, defining the loop dimensions.
+ Generalized ufuncs are used internally in many linalg functions, and in
+ the testing suite; the examples below are taken from these.
+ For ufuncs that operate on scalars, the signature is None, which is
+ equivalent to '()' for every argument.
+ >>> np.core.umath_tests.matrix_multiply.signature
+ '(m,n),(n,p)->(m,p)'
+ >>> np.linalg._umath_linalg.det.signature
+ '(m,m)->()'
+ >>> np.add.signature is None
+ True # equivalent to '(),()->()'
+# ufunc methods
+add_newdoc('numpy.core', 'ufunc', ('reduce',
+ reduce(array, axis=0, dtype=None, out=None, keepdims=False, initial=<no value>, where=True)
+ Reduces `array`'s dimension by one, by applying ufunc along one axis.
+ Let :math:`array.shape = (N_0, ..., N_i, ..., N_{M-1})`. Then
+ :math:`ufunc.reduce(array, axis=i)[k_0, ..,k_{i-1}, k_{i+1}, .., k_{M-1}]` =
+ the result of iterating `j` over :math:`range(N_i)`, cumulatively applying
+ ufunc to each :math:`array[k_0, ..,k_{i-1}, j, k_{i+1}, .., k_{M-1}]`.
+ For a one-dimensional array, reduce produces results equivalent to:
+ ::
+ r = op.identity # op = ufunc
+ for i in range(len(A)):
+ r = op(r, A[i])
+ return r
+ For example, add.reduce() is equivalent to sum().
+ array : array_like
+ The array to act on.
+ axis : None or int or tuple of ints, optional
+ Axis or axes along which a reduction is performed.
+ The default (`axis` = 0) is perform a reduction over the first
+ dimension of the input array. `axis` may be negative, in
+ which case it counts from the last to the first axis.
+ .. versionadded:: 1.7.0
+ If this is None, a reduction is performed over all the axes.
+ If this is a tuple of ints, a reduction is performed on multiple
+ axes, instead of a single axis or all the axes as before.
+ For operations which are either not commutative or not associative,
+ doing a reduction over multiple axes is not well-defined. The
+ ufuncs do not currently raise an exception in this case, but will
+ likely do so in the future.
+ dtype : data-type code, optional
+ The type used to represent the intermediate results. Defaults
+ to the data-type of the output array if this is provided, or
+ the data-type of the input array if no output array is provided.
+ A location into which the result is stored. If not provided or None,
+ a freshly-allocated array is returned. For consistency with
+ ``ufunc.__call__``, if given as a keyword, this may be wrapped in a
+ 1-element tuple.
+ .. versionchanged:: 1.13.0
+ Tuples are allowed for keyword argument.
+ 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 original `array`.
+ initial : scalar, optional
+ The value with which to start the reduction.
+ If the ufunc has no identity or the dtype is object, this defaults
+ to None - otherwise it defaults to ufunc.identity.
+ If ``None`` is given, the first element of the reduction is used,
+ and an error is thrown if the reduction is empty.
+ where : array_like of bool, optional
+ A boolean array which is broadcasted to match the dimensions
+ of `array`, and selects elements to include in the reduction. Note
+ that for ufuncs like ``minimum`` that do not have an identity
+ defined, one has to pass in also ``initial``.
+ r : ndarray
+ The reduced array. If `out` was supplied, `r` is a reference to it.
+ >>> np.multiply.reduce([2,3,5])
+ A multi-dimensional array example:
+ >>> X = np.arange(8).reshape((2,2,2))
+ >>> X
+ array([[[0, 1],
+ [2, 3]],
+ [[4, 5],
+ [6, 7]]])
+ >>> np.add.reduce(X, 0)
+ array([[ 4, 6],
+ [ 8, 10]])
+ >>> np.add.reduce(X) # confirm: default axis value is 0
+ >>> np.add.reduce(X, 1)
+ array([[ 2, 4],
+ [10, 12]])
+ >>> np.add.reduce(X, 2)
+ array([[ 1, 5],
+ [ 9, 13]])
+ You can use the ``initial`` keyword argument to initialize the reduction
+ with a different value, and ``where`` to select specific elements to include:
+ >>> np.add.reduce([10], initial=5)
+ 15
+ >>> np.add.reduce(np.ones((2, 2, 2)), axis=(0, 2), initial=10)
+ array([14., 14.])
+ >>> a = np.array([10., np.nan, 10])
+ >>> np.add.reduce(a, where=~np.isnan(a))
+ 20.0
+ Allows reductions of empty arrays where they would normally fail, i.e.
+ for ufuncs without an identity.
+ >>> np.minimum.reduce([], initial=np.inf)
+ inf
+ >>> np.minimum.reduce([[1., 2.], [3., 4.]], initial=10., where=[True, False])
+ array([ 1., 10.])
+ >>> np.minimum.reduce([])
+ ValueError: zero-size array to reduction operation minimum which has no identity
+add_newdoc('numpy.core', 'ufunc', ('accumulate',
+ accumulate(array, axis=0, dtype=None, out=None)
+ Accumulate the result of applying the operator to all elements.
+ For a one-dimensional array, accumulate produces results equivalent to::
+ r = np.empty(len(A))
+ t = op.identity # op = the ufunc being applied to A's elements
+ t = op(t, A[i])
+ r[i] = t
+ For example, add.accumulate() is equivalent to np.cumsum().
+ For a multi-dimensional array, accumulate is applied along only one
+ axis (axis zero by default; see Examples below) so repeated use is
+ necessary if one wants to accumulate over multiple axes.
+ The axis along which to apply the accumulation; default is zero.
+ The data-type used to represent the intermediate results. Defaults
+ to the data-type of the output array if such is provided, or the
+ The accumulated values. If `out` was supplied, `r` is a reference to
+ `out`.
+ 1-D array examples:
+ >>> np.add.accumulate([2, 3, 5])
+ array([ 2, 5, 10])
+ >>> np.multiply.accumulate([2, 3, 5])
+ array([ 2, 6, 30])
+ 2-D array examples:
+ >>> I = np.eye(2)
+ >>> I
+ [0., 1.]])
+ Accumulate along axis 0 (rows), down columns:
+ >>> np.add.accumulate(I, 0)
+ [1., 1.]])
+ >>> np.add.accumulate(I) # no axis specified = axis zero
+ Accumulate along axis 1 (columns), through rows:
+ >>> np.add.accumulate(I, 1)
+ array([[1., 1.],
+add_newdoc('numpy.core', 'ufunc', ('reduceat',
+ reduceat(array, indices, axis=0, dtype=None, out=None)
+ Performs a (local) reduce with specified slices over a single axis.
+ For i in ``range(len(indices))``, `reduceat` computes
+ ``ufunc.reduce(array[indices[i]:indices[i+1]])``, which becomes the i-th
+ generalized "row" parallel to `axis` in the final result (i.e., in a
+ 2-D array, for example, if `axis = 0`, it becomes the i-th row, but if
+ `axis = 1`, it becomes the i-th column). There are three exceptions to this:
+ * when ``i = len(indices) - 1`` (so for the last index),
+ ``indices[i+1] = array.shape[axis]``.
+ * if ``indices[i] >= indices[i + 1]``, the i-th generalized "row" is
+ simply ``array[indices[i]]``.
+ * if ``indices[i] >= len(array)`` or ``indices[i] < 0``, an error is raised.
+ The shape of the output depends on the size of `indices`, and may be
+ larger than `array` (this happens if ``len(indices) > array.shape[axis]``).
+ indices : array_like
+ Paired indices, comma separated (not colon), specifying slices to
+ reduce.
+ The axis along which to apply the reduceat.
+ to the data type of the output array if this is provided, or
+ the data type of the input array if no output array is provided.
+ The reduced values. If `out` was supplied, `r` is a reference to
+ A descriptive example:
+ If `array` is 1-D, the function `ufunc.accumulate(array)` is the same as
+ ``ufunc.reduceat(array, indices)[::2]`` where `indices` is
+ ``range(len(array) - 1)`` with a zero placed
+ in every other element:
+ ``indices = zeros(2 * len(array) - 1)``,
+ ``indices[1::2] = range(1, len(array))``.
+ Don't be fooled by this attribute's name: `reduceat(array)` is not
+ necessarily smaller than `array`.
+ To take the running sum of four successive values:
+ >>> np.add.reduceat(np.arange(8),[0,4, 1,5, 2,6, 3,7])[::2]
+ array([ 6, 10, 14, 18])
+ A 2-D example:
+ >>> x = np.linspace(0, 15, 16).reshape(4,4)
+ array([[ 0., 1., 2., 3.],
+ [ 4., 5., 6., 7.],
+ [ 8., 9., 10., 11.],
+ [12., 13., 14., 15.]])
+ # reduce such that the result has the following five rows:
+ # [row1 + row2 + row3]
+ # [row4]
+ # [row2]
+ # [row3]
+ # [row1 + row2 + row3 + row4]
+ >>> np.add.reduceat(x, [0, 3, 1, 2, 0])
+ array([[12., 15., 18., 21.],
+ [12., 13., 14., 15.],
+ [24., 28., 32., 36.]])
+ # reduce such that result has the following two columns:
+ # [col1 * col2 * col3, col4]
+ >>> np.multiply.reduceat(x, [0, 3], 1)
+ array([[ 0., 3.],
+ [ 120., 7.],
+ [ 720., 11.],
+ [2184., 15.]])
+add_newdoc('numpy.core', 'ufunc', ('outer',
+ r"""
+ outer(A, B, /, **kwargs)
+ Apply the ufunc `op` to all pairs (a, b) with a in `A` and b in `B`.
+ Let ``M = A.ndim``, ``N = B.ndim``. Then the result, `C`, of
+ ``op.outer(A, B)`` is an array of dimension M + N such that:
+ .. math:: C[i_0, ..., i_{M-1}, j_0, ..., j_{N-1}] =
+ op(A[i_0, ..., i_{M-1}], B[j_0, ..., j_{N-1}])
+ For `A` and `B` one-dimensional, this is equivalent to::
+ r = empty(len(A),len(B))
+ for j in range(len(B)):
+ r[i,j] = op(A[i], B[j]) # op = ufunc in question
+ A : array_like
+ First array
+ B : array_like
+ Second array
+ kwargs : any
+ Arguments to pass on to the ufunc. Typically `dtype` or `out`.
+ Output array
+ numpy.outer : A less powerful version of ``np.multiply.outer``
+ that `ravel`\ s all inputs to 1D. This exists
+ primarily for compatibility with old code.
+ tensordot : ``np.tensordot(a, b, axes=((), ()))`` and
+ ``np.multiply.outer(a, b)`` behave same for all
+ dimensions of a and b.
+ >>> np.multiply.outer([1, 2, 3], [4, 5, 6])
+ array([[ 4, 5, 6],
+ [ 8, 10, 12],
+ [12, 15, 18]])
+ A multi-dimensional example:
+ >>> A = np.array([[1, 2, 3], [4, 5, 6]])
+ >>> A.shape
+ (2, 3)
+ >>> B = np.array([[1, 2, 3, 4]])
+ >>> B.shape
+ >>> C = np.multiply.outer(A, B)
+ >>> C.shape; C
+ (2, 3, 1, 4)
+ array([[[[ 1, 2, 3, 4]],
+ [[ 2, 4, 6, 8]],
+ [[ 3, 6, 9, 12]]],
+ [[[ 4, 8, 12, 16]],
+ [[ 5, 10, 15, 20]],
+ [[ 6, 12, 18, 24]]]])
+add_newdoc('numpy.core', 'ufunc', ('at',
+ at(a, indices, b=None, /)
+ Performs unbuffered in place operation on operand 'a' for elements
+ specified by 'indices'. For addition ufunc, this method is equivalent to
+ ``a[indices] += b``, except that results are accumulated for elements that
+ are indexed more than once. For example, ``a[[0,0]] += 1`` will only
+ increment the first element once because of buffering, whereas
+ ``add.at(a, [0,0], 1)`` will increment the first element twice.
+ a : array_like
+ The array to perform in place operation on.
+ indices : array_like or tuple
+ Array like index object or slice object for indexing into first
+ operand. If first operand has multiple dimensions, indices can be a
+ tuple of array like index objects or slice objects.
+ b : array_like
+ Second operand for ufuncs requiring two operands. Operand must be
+ broadcastable over first operand after indexing or slicing.
+ Set items 0 and 1 to their negative values:
+ >>> a = np.array([1, 2, 3, 4])
+ >>> np.negative.at(a, [0, 1])
+ array([-1, -2, 3, 4])
+ Increment items 0 and 1, and increment item 2 twice:
+ >>> np.add.at(a, [0, 1, 2, 2], 1)
+ array([2, 3, 5, 4])
+ Add items 0 and 1 in first array to second array,
+ and store results in first array:
+ >>> b = np.array([1, 2])
+ >>> np.add.at(a, [0, 1], b)
+ array([2, 4, 3, 4])
+# Documentation for dtype attributes and methods
+# dtype object
+add_newdoc('numpy.core.multiarray', 'dtype',
+ dtype(dtype, align=False, copy=False)
+ Create a data type object.
+ A numpy array is homogeneous, and contains elements described by a
+ dtype object. A dtype object can be constructed from different
+ combinations of fundamental numeric types.
+ dtype
+ Object to be converted to a data type object.
+ Add padding to the fields to match what a C compiler would output
+ for a similar C-struct. Can be ``True`` only if `obj` is a dictionary
+ or a comma-separated string. If a struct dtype is being created,
+ this also sets a sticky alignment flag ``isalignedstruct``.
+ Make a new copy of the data-type object. If ``False``, the result
+ may just be a reference to a built-in data-type object.
+ result_type
+ Using array-scalar type:
+ >>> np.dtype(np.int16)
+ dtype('int16')
+ Structured type, one field name 'f1', containing int16:
+ >>> np.dtype([('f1', np.int16)])
+ dtype([('f1', '<i2')])
+ Structured type, one field named 'f1', in itself containing a structured
+ type with one field:
+ >>> np.dtype([('f1', [('f1', np.int16)])])
+ dtype([('f1', [('f1', '<i2')])])
+ Structured type, two fields: the first field contains an unsigned int, the
+ second an int32:
+ >>> np.dtype([('f1', np.uint64), ('f2', np.int32)])
+ dtype([('f1', '<u8'), ('f2', '<i4')])
+ Using array-protocol type strings:
+ >>> np.dtype([('a','f8'),('b','S10')])
+ dtype([('a', '<f8'), ('b', 'S10')])
+ Using comma-separated field formats. The shape is (2,3):
+ >>> np.dtype("i4, (2,3)f8")
+ dtype([('f0', '<i4'), ('f1', '<f8', (2, 3))])
+ Using tuples. ``int`` is a fixed type, 3 the field's shape. ``void``
+ is a flexible type, here of size 10:
+ >>> np.dtype([('hello',(np.int64,3)),('world',np.void,10)])
+ dtype([('hello', '<i8', (3,)), ('world', 'V10')])
+ Subdivide ``int16`` into 2 ``int8``'s, called x and y. 0 and 1 are
+ the offsets in bytes:
+ >>> np.dtype((np.int16, {'x':(np.int8,0), 'y':(np.int8,1)}))
+ dtype((numpy.int16, [('x', 'i1'), ('y', 'i1')]))
+ Using dictionaries. Two fields named 'gender' and 'age':
+ >>> np.dtype({'names':['gender','age'], 'formats':['S1',np.uint8]})
+ dtype([('gender', 'S1'), ('age', 'u1')])
+ Offsets in bytes, here 0 and 25:
+ >>> np.dtype({'surname':('S25',0),'age':(np.uint8,25)})
+ dtype([('surname', 'S25'), ('age', 'u1')])
+# dtype attributes
+add_newdoc('numpy.core.multiarray', 'dtype', ('alignment',
+ The required alignment (bytes) of this data-type according to the compiler.
+ More information is available in the C-API section of the manual.
+ >>> x = np.dtype('i4')
+ >>> x.alignment
+ >>> x = np.dtype(float)
+add_newdoc('numpy.core.multiarray', 'dtype', ('byteorder',
+ A character indicating the byte-order of this data-type object.
+ One of:
+ === ==============
+ '=' native
+ '<' little-endian
+ '>' big-endian
+ '|' not applicable
+ All built-in data-type objects have byteorder either '=' or '|'.
+ >>> dt = np.dtype('i2')
+ >>> dt.byteorder
+ '='
+ >>> # endian is not relevant for 8 bit numbers
+ >>> np.dtype('i1').byteorder
+ '|'
+ >>> # or ASCII strings
+ >>> np.dtype('S2').byteorder
+ >>> # Even if specific code is given, and it is native
+ >>> # '=' is the byteorder
+ >>> import sys
+ >>> sys_is_le = sys.byteorder == 'little'
+ >>> native_code = sys_is_le and '<' or '>'
+ >>> swapped_code = sys_is_le and '>' or '<'
+ >>> dt = np.dtype(native_code + 'i2')
+ >>> # Swapped code shows up as itself
+ >>> dt = np.dtype(swapped_code + 'i2')
+ >>> dt.byteorder == swapped_code
+add_newdoc('numpy.core.multiarray', 'dtype', ('char',
+ """A unique character code for each of the 21 different built-in types.
+ >>> x.char
+ 'd'
+add_newdoc('numpy.core.multiarray', 'dtype', ('descr',
+ `__array_interface__` description of the data-type.
+ The format is that required by the 'descr' key in the
+ `__array_interface__` attribute.
+ Warning: This attribute exists specifically for `__array_interface__`,
+ and passing it directly to `np.dtype` will not accurately reconstruct
+ some dtypes (e.g., scalar and subarray dtypes).
+ >>> x.descr
+ [('', '<f8')]
+ >>> dt = np.dtype([('name', np.str_, 16), ('grades', np.float64, (2,))])
+ >>> dt.descr
+ [('name', '<U16'), ('grades', '<f8', (2,))]
+add_newdoc('numpy.core.multiarray', 'dtype', ('fields',
+ Dictionary of named fields defined for this data type, or ``None``.
+ The dictionary is indexed by keys that are the names of the fields.
+ Each entry in the dictionary is a tuple fully describing the field::
+ (dtype, offset[, title])
+ Offset is limited to C int, which is signed and usually 32 bits.
+ If present, the optional title can be any object (if it is a string
+ or unicode then it will also be a key in the fields dictionary,
+ otherwise it's meta-data). Notice also that the first two elements
+ of the tuple can be passed directly as arguments to the ``ndarray.getfield``
+ and ``ndarray.setfield`` methods.
+ ndarray.getfield, ndarray.setfield
+ >>> print(dt.fields)
+ {'grades': (dtype(('float64',(2,))), 16), 'name': (dtype('|S16'), 0)}
+add_newdoc('numpy.core.multiarray', 'dtype', ('flags',
+ Bit-flags describing how this data type is to be interpreted.
+ Bit-masks are in `numpy.core.multiarray` as the constants
+ `ITEM_HASOBJECT`, `LIST_PICKLE`, `ITEM_IS_POINTER`, `NEEDS_INIT`,
+ `NEEDS_PYAPI`, `USE_GETITEM`, `USE_SETITEM`. A full explanation
+ of these flags is in C-API documentation; they are largely useful
+ for user-defined data-types.
+ The following example demonstrates that operations on this particular
+ dtype requires Python C-API.
+ >>> x = np.dtype([('a', np.int32, 8), ('b', np.float64, 6)])
+ >>> x.flags
+ >>> np.core.multiarray.NEEDS_PYAPI
+add_newdoc('numpy.core.multiarray', 'dtype', ('hasobject',
+ Boolean indicating whether this dtype contains any reference-counted
+ objects in any fields or sub-dtypes.
+ Recall that what is actually in the ndarray memory representing
+ the Python object is the memory address of that object (a pointer).
+ Special handling may be required, and this attribute is useful for
+ distinguishing data types that may contain arbitrary Python objects
+ and data-types that won't.
+add_newdoc('numpy.core.multiarray', 'dtype', ('isbuiltin',
+ Integer indicating how this dtype relates to the built-in dtypes.
+ Read-only.
+ = ========================================================================
+ 0 if this is a structured array type, with fields
+ 1 if this is a dtype compiled into numpy (such as ints, floats etc)
+ 2 if the dtype is for a user-defined numpy type
+ A user-defined type uses the numpy C-API machinery to extend
+ numpy to handle a new array type. See
+ :ref:`user.user-defined-data-types` in the NumPy manual.
+ >>> dt.isbuiltin
+ >>> dt = np.dtype('f8')
+ >>> dt = np.dtype([('field1', 'f8')])
+add_newdoc('numpy.core.multiarray', 'dtype', ('isnative',
+ Boolean indicating whether the byte order of this dtype is native
+ to the platform.
+add_newdoc('numpy.core.multiarray', 'dtype', ('isalignedstruct',
+ Boolean indicating whether the dtype is a struct which maintains
+ field alignment. This flag is sticky, so when combining multiple
+ structs together, it is preserved and produces new dtypes which
+ are also aligned.
+add_newdoc('numpy.core.multiarray', 'dtype', ('itemsize',
+ The element size of this data-type object.
+ For 18 of the 21 types this number is fixed by the data-type.
+ For the flexible data-types, this number can be anything.
+ >>> arr = np.array([[1, 2], [3, 4]])
+ >>> arr.dtype
+ dtype('int64')
+ >>> arr.itemsize
+ >>> dt.itemsize
+ 80
+add_newdoc('numpy.core.multiarray', 'dtype', ('kind',
+ A character code (one of 'biufcmMOSUV') identifying the general kind of data.
+ = ======================
+ b boolean
+ i signed integer
+ u unsigned integer
+ f floating-point
+ c complex floating-point
+ m timedelta
+ M datetime
+ O object
+ S (byte-)string
+ U Unicode
+ V void
+ >>> dt = np.dtype('i4')
+ >>> dt.kind
+ 'i'
+ 'f'
+ 'V'
+add_newdoc('numpy.core.multiarray', 'dtype', ('metadata',
+ Either ``None`` or a readonly dictionary of metadata (mappingproxy).
+ The metadata field can be set using any dictionary at data-type
+ creation. NumPy currently has no uniform approach to propagating
+ metadata; although some array operations preserve it, there is no
+ guarantee that others will.
+ .. warning::
+ Although used in certain projects, this feature was long undocumented
+ and is not well supported. Some aspects of metadata propagation
+ are expected to change in the future.
+ >>> dt = np.dtype(float, metadata={"key": "value"})
+ >>> dt.metadata["key"]
+ 'value'
+ >>> arr = np.array([1, 2, 3], dtype=dt)
+ >>> arr.dtype.metadata
+ mappingproxy({'key': 'value'})
+ Adding arrays with identical datatypes currently preserves the metadata:
+ >>> (arr + arr).dtype.metadata
+ But if the arrays have different dtype metadata, the metadata may be
+ dropped:
+ >>> dt2 = np.dtype(float, metadata={"key2": "value2"})
+ >>> arr2 = np.array([3, 2, 1], dtype=dt2)
+ >>> (arr + arr2).dtype.metadata is None
+ True # The metadata field is cleared so None is returned
+add_newdoc('numpy.core.multiarray', 'dtype', ('name',
+ A bit-width name for this data-type.
+ Un-sized flexible data-type objects do not have this attribute.
+ >>> x.name
+ 'float64'
+ 'void640'
+add_newdoc('numpy.core.multiarray', 'dtype', ('names',
+ Ordered list of field names, or ``None`` if there are no fields.
+ The names are ordered according to increasing byte offset. This can be
+ used, for example, to walk through all of the named fields in offset order.
+ >>> dt.names
+ ('name', 'grades')
+add_newdoc('numpy.core.multiarray', 'dtype', ('num',
+ A unique number for each of the 21 different built-in types.
+ These are roughly ordered from least-to-most precision.
+ >>> dt = np.dtype(str)
+ >>> dt.num
+ 19
+ >>> dt = np.dtype(float)
+ 12
+add_newdoc('numpy.core.multiarray', 'dtype', ('shape',
+ Shape tuple of the sub-array if this data type describes a sub-array,
+ and ``()`` otherwise.
+ >>> dt = np.dtype(('i4', 4))
+ >>> dt.shape
+ >>> dt = np.dtype(('i4', (2, 3)))
+add_newdoc('numpy.core.multiarray', 'dtype', ('ndim',
+ Number of dimensions of the sub-array if this data type describes a
+ sub-array, and ``0`` otherwise.
+ .. versionadded:: 1.13.0
+ >>> x = np.dtype((float, 8))
+ >>> x = np.dtype(('i4', (3, 4)))
+add_newdoc('numpy.core.multiarray', 'dtype', ('str',
+ """The array-protocol typestring of this data-type object."""))
+add_newdoc('numpy.core.multiarray', 'dtype', ('subdtype',
+ Tuple ``(item_dtype, shape)`` if this `dtype` describes a sub-array, and
+ None otherwise.
+ The *shape* is the fixed shape of the sub-array described by this
+ data type, and *item_dtype* the data type of the array.
+ If a field whose dtype object has this attribute is retrieved,
+ then the extra dimensions implied by *shape* are tacked on to
+ the end of the retrieved array.
+ dtype.base
+ >>> x = numpy.dtype('8f')
+ >>> x.subdtype
+ (dtype('float32'), (8,))
+ >>> x = numpy.dtype('i2')
+ >>>
+add_newdoc('numpy.core.multiarray', 'dtype', ('base',
+ Returns dtype for the base element of the subarrays,
+ regardless of their dimension or shape.
+ dtype.subdtype
+ >>> x.base
+ dtype('float32')
+add_newdoc('numpy.core.multiarray', 'dtype', ('type',
+ """The type object used to instantiate a scalar of this data-type."""))
+# dtype methods
+add_newdoc('numpy.core.multiarray', 'dtype', ('newbyteorder',
+ newbyteorder(new_order='S', /)
+ Return a new dtype with a different byte order.
+ Changes are also made in all fields and sub-arrays of the data type.
+ below. The default value ('S') results in swapping the current
+ byte order. `new_order` codes can be any of:
+ * '=' - native order
+ new_dtype : dtype
+ New dtype object with the given change to the byte order.
+ >>> native_dt = np.dtype(native_code+'i2')
+ >>> swapped_dt = np.dtype(swapped_code+'i2')
+ >>> native_dt.newbyteorder('S') == swapped_dt
+ >>> native_dt.newbyteorder() == swapped_dt
+ >>> native_dt == swapped_dt.newbyteorder('S')
+ >>> native_dt == swapped_dt.newbyteorder('=')
+ >>> native_dt == swapped_dt.newbyteorder('N')
+ >>> native_dt == native_dt.newbyteorder('|')
+ >>> np.dtype('<i2') == native_dt.newbyteorder('<')
+ >>> np.dtype('<i2') == native_dt.newbyteorder('L')
+ >>> np.dtype('>i2') == native_dt.newbyteorder('>')
+ >>> np.dtype('>i2') == native_dt.newbyteorder('B')
+# Datetime-related Methods
+add_newdoc('numpy.core.multiarray', 'busdaycalendar',
+ busdaycalendar(weekmask='1111100', holidays=None)
+ A business day calendar object that efficiently stores information
+ defining valid days for the busday family of functions.
+ The default valid days are Monday through Friday ("business days").
+ A busdaycalendar object can be specified with any set of weekly
+ valid days, plus an optional "holiday" dates that always will be invalid.
+ Once a busdaycalendar object is created, the weekmask and holidays
+ cannot be modified.
+ weekmask : str or array_like of bool, optional
+ A seven-element array indicating which of Monday through Sunday are
+ valid days. May be specified as a length-seven list or array, like
+ [1,1,1,1,1,0,0]; a length-seven string, like '1111100'; or a string
+ like "Mon Tue Wed Thu Fri", made up of 3-character abbreviations for
+ weekdays, optionally separated by white space. Valid abbreviations
+ are: Mon Tue Wed Thu Fri Sat Sun
+ holidays : array_like of datetime64[D], optional
+ An array of dates to consider as invalid dates, no matter which
+ weekday they fall upon. Holiday dates may be specified in any
+ order, and NaT (not-a-time) dates are ignored. This list is
+ saved in a normalized form that is suited for fast calculations
+ of valid days.
+ out : busdaycalendar
+ A business day calendar object containing the specified
+ weekmask and holidays values.
+ is_busday : Returns a boolean array indicating 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.
+ Note: once a busdaycalendar object is created, you cannot modify the
+ weekmask or holidays. The attributes return copies of internal data.
+ weekmask : (copy) seven-element array of bool
+ holidays : (copy) sorted array of datetime64[D]
+ >>> # Some important days in July
+ ... bdd = np.busdaycalendar(
+ ... holidays=['2011-07-01', '2011-07-04', '2011-07-17'])
+ >>> # Default is Monday to Friday weekdays
+ ... bdd.weekmask
+ array([ True, True, True, True, True, False, False])
+ >>> # Any holidays already on the weekend are removed
+ ... bdd.holidays
+ array(['2011-07-01', '2011-07-04'], dtype='datetime64[D]')
+add_newdoc('numpy.core.multiarray', 'busdaycalendar', ('weekmask',
+ """A copy of the seven-element boolean mask indicating valid days."""))
+add_newdoc('numpy.core.multiarray', 'busdaycalendar', ('holidays',
+ """A copy of the holiday array indicating additional invalid days."""))
+add_newdoc('numpy.core.multiarray', 'normalize_axis_index',
+ normalize_axis_index(axis, ndim, msg_prefix=None)
+ Normalizes an axis index, `axis`, such that is a valid positive index into
+ the shape of array with `ndim` dimensions. Raises an AxisError with an
+ appropriate message if this is not possible.
+ Used internally by all axis-checking logic.
+ axis : int
+ The un-normalized index of the axis. Can be negative
+ The number of dimensions of the array that `axis` should be normalized
+ against
+ msg_prefix : str
+ A prefix to put before the message, typically the name of the argument
+ normalized_axis : int
+ The normalized axis index, such that `0 <= normalized_axis < ndim`
+ AxisError
+ If the axis index is invalid, when `-ndim <= axis < ndim` is false.
+ >>> normalize_axis_index(0, ndim=3)
+ >>> normalize_axis_index(1, ndim=3)
+ >>> normalize_axis_index(-1, ndim=3)
+ >>> normalize_axis_index(3, ndim=3)
+ AxisError: axis 3 is out of bounds for array of dimension 3
+ >>> normalize_axis_index(-4, ndim=3, msg_prefix='axes_arg')
+ AxisError: axes_arg: axis -4 is out of bounds for array of dimension 3
+add_newdoc('numpy.core.multiarray', 'datetime_data',
+ datetime_data(dtype, /)
+ Get information about the step size of a date or time type.
+ The returned tuple can be passed as the second argument of `numpy.datetime64` and
+ `numpy.timedelta64`.
+ The dtype object, which must be a `datetime64` or `timedelta64` type.
+ unit : str
+ The :ref:`datetime unit <arrays.dtypes.dateunits>` on which this dtype
+ is based.
+ The number of base units in a step.
+ >>> dt_25s = np.dtype('timedelta64[25s]')
+ >>> np.datetime_data(dt_25s)
+ ('s', 25)
+ >>> np.array(10, dt_25s).astype('timedelta64[s]')
+ array(250, dtype='timedelta64[s]')
+ The result can be used to construct a datetime that uses the same units
+ as a timedelta
+ >>> np.datetime64('2010', np.datetime_data(dt_25s))
+ numpy.datetime64('2010-01-01T00:00:00','25s')
+# Documentation for `generic` attributes and methods
+add_newdoc('numpy.core.numerictypes', 'generic',
+ Base class for numpy scalar types.
+ Class from which most (all?) numpy scalar types are derived. For
+ consistency, exposes the same API as `ndarray`, despite many
+ consequent attributes being either "get-only," or completely irrelevant.
+ This is the class from which it is strongly suggested users should derive
+ custom scalar types.
+# Attributes
+def refer_to_array_attribute(attr, method=True):
+ docstring = """
+ Scalar {} identical to the corresponding array attribute.
+ Please see `ndarray.{}`.
+ return attr, docstring.format("method" if method else "attribute", attr)
+ refer_to_array_attribute('T', method=False))
+ refer_to_array_attribute('base', method=False))
+add_newdoc('numpy.core.numerictypes', 'generic', ('data',
+ """Pointer to start of data."""))
+add_newdoc('numpy.core.numerictypes', 'generic', ('dtype',
+ """Get array data-descriptor."""))
+add_newdoc('numpy.core.numerictypes', 'generic', ('flags',
+ """The integer value of flags."""))
+add_newdoc('numpy.core.numerictypes', 'generic', ('flat',
+ """A 1-D view of the scalar."""))
+add_newdoc('numpy.core.numerictypes', 'generic', ('imag',
+ """The imaginary part of the scalar."""))
+add_newdoc('numpy.core.numerictypes', 'generic', ('itemsize',
+ """The length of one element in bytes."""))
+add_newdoc('numpy.core.numerictypes', 'generic', ('nbytes',
+ """The length of the scalar in bytes."""))
+add_newdoc('numpy.core.numerictypes', 'generic', ('ndim',
+ """The number of array dimensions."""))
+add_newdoc('numpy.core.numerictypes', 'generic', ('real',
+ """The real part of the scalar."""))
+add_newdoc('numpy.core.numerictypes', 'generic', ('shape',
+ """Tuple of array dimensions."""))
+add_newdoc('numpy.core.numerictypes', 'generic', ('size',
+ """The number of elements in the gentype."""))
+add_newdoc('numpy.core.numerictypes', 'generic', ('strides',
+ """Tuple of bytes steps in each dimension."""))
+# Methods
+ refer_to_array_attribute('all'))
+ refer_to_array_attribute('any'))
+ refer_to_array_attribute('argmax'))
+ refer_to_array_attribute('argmin'))
+ refer_to_array_attribute('argsort'))
+ refer_to_array_attribute('astype'))
+ refer_to_array_attribute('byteswap'))
+ refer_to_array_attribute('choose'))
+ refer_to_array_attribute('clip'))
+ refer_to_array_attribute('compress'))
+ refer_to_array_attribute('conjugate'))
+ refer_to_array_attribute('copy'))
+ refer_to_array_attribute('cumprod'))
+ refer_to_array_attribute('cumsum'))
+ refer_to_array_attribute('diagonal'))
+ refer_to_array_attribute('dump'))
+ refer_to_array_attribute('dumps'))
+ refer_to_array_attribute('fill'))
+ refer_to_array_attribute('flatten'))
+ refer_to_array_attribute('getfield'))
+ refer_to_array_attribute('item'))
+ refer_to_array_attribute('itemset'))
+ refer_to_array_attribute('max'))
+ refer_to_array_attribute('mean'))
+ refer_to_array_attribute('min'))
+add_newdoc('numpy.core.numerictypes', 'generic', ('newbyteorder',
+ Return a new `dtype` with a different byte order.
+ The `new_order` code can be any from the following:
+ new_order : str, optional
+ above. The default value ('S') results in swapping the current
+ New `dtype` object with the given change to the byte order.
+ refer_to_array_attribute('nonzero'))
+ refer_to_array_attribute('prod'))
+ refer_to_array_attribute('ptp'))
+ refer_to_array_attribute('put'))
+ refer_to_array_attribute('ravel'))
+ refer_to_array_attribute('repeat'))
+ refer_to_array_attribute('reshape'))
+ refer_to_array_attribute('resize'))
+ refer_to_array_attribute('round'))
+ refer_to_array_attribute('searchsorted'))
+ refer_to_array_attribute('setfield'))
+ refer_to_array_attribute('setflags'))
+ refer_to_array_attribute('sort'))
+ refer_to_array_attribute('squeeze'))
+ refer_to_array_attribute('std'))
+ refer_to_array_attribute('sum'))
+ refer_to_array_attribute('swapaxes'))
+ refer_to_array_attribute('take'))
+ refer_to_array_attribute('tofile'))
+ refer_to_array_attribute('tolist'))
+ refer_to_array_attribute('tostring'))
+ refer_to_array_attribute('trace'))
+ refer_to_array_attribute('transpose'))
+ refer_to_array_attribute('var'))
+ refer_to_array_attribute('view'))
+# Documentation for scalar type abstract base classes in type hierarchy
+add_newdoc('numpy.core.numerictypes', 'number',
+ Abstract base class of all numeric scalar types.
+add_newdoc('numpy.core.numerictypes', 'integer',
+ Abstract base class of all integer scalar types.
+add_newdoc('numpy.core.numerictypes', 'signedinteger',
+ Abstract base class of all signed integer scalar types.
+add_newdoc('numpy.core.numerictypes', 'unsignedinteger',
+ Abstract base class of all unsigned integer scalar types.
+add_newdoc('numpy.core.numerictypes', 'inexact',
+ Abstract base class of all numeric scalar types with a (potentially)
+ inexact representation of the values in its range, such as
+ floating-point numbers.
+add_newdoc('numpy.core.numerictypes', 'floating',
+ Abstract base class of all floating-point scalar types.
+add_newdoc('numpy.core.numerictypes', 'complexfloating',
+ Abstract base class of all complex number scalar types that are made up of
+add_newdoc('numpy.core.numerictypes', 'flexible',
+ Abstract base class of all scalar types without predefined length.
+ The actual size of these types depends on the specific `np.dtype`
+ instantiation.
+add_newdoc('numpy.core.numerictypes', 'character',
+ Abstract base class of all character string scalar types.
@@ -0,0 +1,251 @@
+This file is separate from ``_add_newdocs.py`` so that it can be mocked out by
+our sphinx ``conf.py`` during doc builds, where we want to avoid showing
+platform-dependent information.
+from numpy.core import dtype
+from numpy.core import numerictypes as _numerictypes
+# Documentation for concrete scalar classes
+def numeric_type_aliases(aliases):
+ def type_aliases_gen():
+ for alias, doc in aliases:
+ alias_type = getattr(_numerictypes, alias)
+ except AttributeError:
+ # The set of aliases that actually exist varies between platforms
+ yield (alias_type, alias, doc)
+ return list(type_aliases_gen())
+possible_aliases = numeric_type_aliases([
+ ('int8', '8-bit signed integer (``-128`` to ``127``)'),
+ ('int16', '16-bit signed integer (``-32_768`` to ``32_767``)'),
+ ('int32', '32-bit signed integer (``-2_147_483_648`` to ``2_147_483_647``)'),
+ ('int64', '64-bit signed integer (``-9_223_372_036_854_775_808`` to ``9_223_372_036_854_775_807``)'),
+ ('intp', 'Signed integer large enough to fit pointer, compatible with C ``intptr_t``'),
+ ('uint8', '8-bit unsigned integer (``0`` to ``255``)'),
+ ('uint16', '16-bit unsigned integer (``0`` to ``65_535``)'),
+ ('uint32', '32-bit unsigned integer (``0`` to ``4_294_967_295``)'),
+ ('uint64', '64-bit unsigned integer (``0`` to ``18_446_744_073_709_551_615``)'),
+ ('uintp', 'Unsigned integer large enough to fit pointer, compatible with C ``uintptr_t``'),
+ ('float16', '16-bit-precision floating-point number type: sign bit, 5 bits exponent, 10 bits mantissa'),
+ ('float32', '32-bit-precision floating-point number type: sign bit, 8 bits exponent, 23 bits mantissa'),
+ ('float64', '64-bit precision floating-point number type: sign bit, 11 bits exponent, 52 bits mantissa'),
+ ('float96', '96-bit extended-precision floating-point number type'),
+ ('float128', '128-bit extended-precision floating-point number type'),
+ ('complex64', 'Complex number type composed of 2 32-bit-precision floating-point numbers'),
+ ('complex128', 'Complex number type composed of 2 64-bit-precision floating-point numbers'),
+ ('complex192', 'Complex number type composed of 2 96-bit extended-precision floating-point numbers'),
+ ('complex256', 'Complex number type composed of 2 128-bit extended-precision floating-point numbers'),
+ ])
+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)
+ 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)
+ for (alias_type, alias, doc) in possible_aliases if alias_type is o)
+ {doc}
+ :Character code: ``'{character_code}'``
+ {canonical_name_doc}{alias_doc}
+ """.format(doc=doc.strip(), character_code=character_code,
+ canonical_name_doc=canonical_name_doc, alias_doc=alias_doc)
+ add_newdoc('numpy.core.numerictypes', obj, docstring)
+add_newdoc_for_scalar_type('bool_', ['bool8'],
+ Boolean type (True or False), stored as a byte.
+ The :class:`bool_` type is not a subclass of the :class:`int_` type
+ (the :class:`bool_` is not even a number type). This is different
+ than Python's default implementation of :class:`bool` as a
+ sub-class of :class:`int`.
+add_newdoc_for_scalar_type('byte', [],
+ Signed integer type, compatible with C ``char``.
+add_newdoc_for_scalar_type('short', [],
+ Signed integer type, compatible with C ``short``.
+add_newdoc_for_scalar_type('intc', [],
+ Signed integer type, compatible with C ``int``.
+add_newdoc_for_scalar_type('int_', [],
+ Signed integer type, compatible with Python `int` and C ``long``.
+add_newdoc_for_scalar_type('longlong', [],
+ Signed integer type, compatible with C ``long long``.
+add_newdoc_for_scalar_type('ubyte', [],
+ Unsigned integer type, compatible with C ``unsigned char``.
+add_newdoc_for_scalar_type('ushort', [],
+ Unsigned integer type, compatible with C ``unsigned short``.
+add_newdoc_for_scalar_type('uintc', [],
+ Unsigned integer type, compatible with C ``unsigned int``.
+add_newdoc_for_scalar_type('uint', [],
+ Unsigned integer type, compatible with C ``unsigned long``.
+add_newdoc_for_scalar_type('ulonglong', [],
+ Signed integer type, compatible with C ``unsigned long long``.
+add_newdoc_for_scalar_type('half', [],
+ Half-precision floating-point number type.
+add_newdoc_for_scalar_type('single', [],
+ Single-precision floating-point number type, compatible with C ``float``.
+add_newdoc_for_scalar_type('double', ['float_'],
+ Double-precision floating-point number type, compatible with Python `float`
+ and C ``double``.
+add_newdoc_for_scalar_type('longdouble', ['longfloat'],
+ Extended-precision floating-point number type, compatible with C
+ ``long double`` but not necessarily with IEEE 754 quadruple-precision.
+add_newdoc_for_scalar_type('csingle', ['singlecomplex'],
+ Complex number type composed of two single-precision floating-point
+ numbers.
+add_newdoc_for_scalar_type('cdouble', ['cfloat', 'complex_'],
+ Complex number type composed of two double-precision floating-point
+ numbers, compatible with Python `complex`.
+add_newdoc_for_scalar_type('clongdouble', ['clongfloat', 'longcomplex'],
+ Complex number type composed of two extended-precision floating-point
+add_newdoc_for_scalar_type('object_', [],
+ Any Python object.
+add_newdoc_for_scalar_type('str_', ['unicode_'],
+ A unicode string.
+ When used in arrays, this type strips trailing null codepoints.
+ Unlike the builtin `str`, this supports the :ref:`python:bufferobjects`, exposing its
+ contents as UCS4:
+ >>> m = memoryview(np.str_("abc"))
+ >>> m.format
+ '3w'
+ >>> m.tobytes()
+ b'a\x00\x00\x00b\x00\x00\x00c\x00\x00\x00'
+add_newdoc_for_scalar_type('bytes_', ['string_'],
+ A byte string.
+ When used in arrays, this type strips trailing null bytes.
+add_newdoc_for_scalar_type('void', [],
+ Either an opaque sequence of bytes, or a structure.
+ >>> np.void(b'abcd')
+ void(b'\x61\x62\x63\x64')
+ Structured `void` scalars can only be constructed via extraction from :ref:`structured_arrays`:
+ >>> arr = np.array((1, 2), dtype=[('x', np.int8), ('y', np.int8)])
+ >>> arr[()]
+ (1, 2) # looks like a tuple, but is `np.void`
+add_newdoc_for_scalar_type('datetime64', [],
+ A datetime stored as a 64-bit integer, counting from ``1970-01-01T00:00:00``.
+ >>> np.datetime64(10, 'Y')
+ numpy.datetime64('1980')
+ >>> np.datetime64(10, 'D')
+ numpy.datetime64('1970-01-11')
+ See :ref:`arrays.datetime` for more information.
+add_newdoc_for_scalar_type('timedelta64', [],
+ A timedelta stored as a 64-bit integer.
+# TODO: work out how to put this on the base class, np.floating
+for float_name in ('half', 'single', 'double', 'longdouble'):
+ add_newdoc('numpy.core.numerictypes', float_name, ('as_integer_ratio',
+ {ftype}.as_integer_ratio() -> (int, int)
+ Return a pair of integers, whose ratio is exactly equal to the original
+ floating point number, and with a positive denominator.
+ Raise `OverflowError` on infinities and a `ValueError` on NaNs.
+ >>> np.{ftype}(10.0).as_integer_ratio()
+ (10, 1)
+ >>> np.{ftype}(0.0).as_integer_ratio()
+ >>> np.{ftype}(-.25).as_integer_ratio()
+ (-1, 4)
+ """.format(ftype=float_name)))
@@ -0,0 +1,411 @@
+Functions in the ``as*array`` family that promote array-likes into arrays.
+`require` fits this category despite its name not matching this pattern.
+from .overrides import (
+ array_function_dispatch,
+ set_array_function_like_doc,
+ set_module,
+from .multiarray import array
+__all__ = [
+ "asarray", "asanyarray", "ascontiguousarray", "asfortranarray", "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.
+ 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.
+ By default, the data-type is inferred from the input data.
+ 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 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.
+ 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.
+ Convert a list into an array:
+ >>> a = [1, 2]
+ >>> np.asarray(a)
+ Existing arrays are not copied:
+ >>> np.asarray(a) is a
+ 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
+ >>> np.asarray(a, dtype=np.float64) is a
+ False
+ Contrary to `asanyarray`, ndarray subclasses are not passed through:
+ >>> issubclass(np.recarray, np.ndarray)
+ >>> a = np.array([(1.0, 2), (3.0, 4)], dtype='f4,i4').view(np.recarray)
+ >>> np.asanyarray(a) is a
+ 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)
+def asanyarray(a, dtype=None, order=None, *, like=None):
+ """Convert the input to an ndarray, but pass ndarray subclasses through.
+ includes scalars, lists, lists of tuples, tuples, tuples of tuples,
+ tuples of lists, and ndarrays.
+ 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.
+ asarray : Similar function which always returns ndarrays.
+ asarray_chkfinite : Similar function which checks input for NaNs and
+ Infs.
+ >>> np.asanyarray(a)
+ Instances of `ndarray` subclasses are passed through as-is:
+ 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(
+)(asanyarray)
+def _asarray_contiguous_fortran_dispatcher(a, dtype=None, *, like=None):
+def ascontiguousarray(a, dtype=None, *, like=None):
+ Return a contiguous array (ndim >= 1) in memory (C order).
+ Input array.
+ dtype : str or dtype object, optional
+ Data-type of returned array.
+ Contiguous array of same shape and content as `a`, with type `dtype`
+ if specified.
+ require : Return an ndarray that satisfies requirements.
+ ndarray.flags : Information about the memory layout of the array.
+ >>> 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']
+ Note: This function returns an array with at least one-dimension (1-d)
+ so it will not preserve 0-d arrays.
+ 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)
+def asfortranarray(a, dtype=None, *, like=None):
+ Return an array (ndim >= 1) laid out in Fortran order in memory.
+ The input `a` in Fortran, or column-major, order.
+ ascontiguousarray : Convert input to a contiguous (C order) array.
+ asanyarray : Convert input to an ndarray with either row or
+ column-major memory order.
+ >>> y = np.asfortranarray(x)
+ >>> x.flags['F_CONTIGUOUS']
+ >>> y.flags['F_CONTIGUOUS']
+ 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(
+)(asfortranarray)
+def _require_dispatcher(a, dtype=None, requirements=None, *, like=None):
+def require(a, dtype=None, requirements=None, *, like=None):
+ Return an ndarray of the provided type that satisfies requirements.
+ This function is useful to be sure that an array with the correct flags
+ is returned for passing to compiled code (perhaps through ctypes).
+ The object to be converted to a type-and-requirement-satisfying array.
+ The required data-type. If None preserve the current dtype. If your
+ application requires the data to be in native byteorder, include
+ a byteorder specification as a part of the dtype specification.
+ requirements : str or list of str
+ The requirements list can be any of the following
+ * 'F_CONTIGUOUS' ('F') - ensure a Fortran-contiguous array
+ * 'C_CONTIGUOUS' ('C') - ensure a C-contiguous array
+ * 'ALIGNED' ('A') - ensure a data-type aligned array
+ * 'WRITEABLE' ('W') - ensure a writable array
+ * 'OWNDATA' ('O') - ensure an array that owns its own data
+ * 'ENSUREARRAY', ('E') - ensure a base array, instead of a subclass
+ Array with specified requirements and type if given.
+ asarray : Convert input to an ndarray.
+ asanyarray : Convert to an ndarray, but pass through ndarray subclasses.
+ The returned array will be guaranteed to have the listed requirements
+ by making a copy if needed.
+ OWNDATA : False
+ >>> y = np.require(x, dtype=np.float32, requirements=['A', 'O', 'W', 'F'])
+ C_CONTIGUOUS : False
+ F_CONTIGUOUS : True
+ return _require_with_like(
+ a,
+ dtype=dtype,
+ requirements=requirements,
+ like=like,
+ possible_flags = {'C': 'C', 'C_CONTIGUOUS': 'C', 'CONTIGUOUS': 'C',
+ 'F': 'F', 'F_CONTIGUOUS': 'F', 'FORTRAN': 'F',
+ 'A': 'A', 'ALIGNED': 'A',
+ 'W': 'W', 'WRITEABLE': 'W',
+ 'O': 'O', 'OWNDATA': 'O',
+ 'E': 'E', 'ENSUREARRAY': 'E'}
+ if not requirements:
+ return asanyarray(a, dtype=dtype)
+ requirements = {possible_flags[x.upper()] for x in requirements}
+ if 'E' in requirements:
+ requirements.remove('E')
+ subok = False
+ subok = True
+ order = 'A'
+ if requirements >= {'C', 'F'}:
+ raise ValueError('Cannot specify both "C" and "F" order')
+ elif 'F' in requirements:
+ order = 'F'
+ requirements.remove('F')
+ elif 'C' in requirements:
+ order = 'C'
+ requirements.remove('C')
+ arr = array(a, dtype=dtype, order=order, copy=False, subok=subok)
+ for prop in requirements:
+ if not arr.flags[prop]:
+ arr = arr.copy(order)
+ break
+ return arr
+_require_with_like = array_function_dispatch(
+ _require_dispatcher
+)(require)
@@ -0,0 +1,77 @@
+from typing import TypeVar, Union, Iterable, overload
+from numpy import ndarray, _OrderKACF
+from numpy.typing import ArrayLike, DTypeLike
+ from typing import Literal
+ from typing_extensions import Literal
+_ArrayType = TypeVar("_ArrayType", bound=ndarray)
+def asarray(
+ a: object,
+ like: ArrayLike = ...
+@overload
+def asanyarray(
+ a: _ArrayType,
+ dtype: None = ...,
+) -> _ArrayType: ...
+def ascontiguousarray(
+ a: object, dtype: DTypeLike = ..., *, like: ArrayLike = ...
+def asfortranarray(
+_Requirements = Literal[
+ "C", "C_CONTIGUOUS", "CONTIGUOUS",
+ "F", "F_CONTIGUOUS", "FORTRAN",
+ "A", "ALIGNED",
+ "W", "WRITEABLE",
+ "O", "OWNDATA"
+_E = Literal["E", "ENSUREARRAY"]
+_RequirementsWithE = Union[_Requirements, _E]
+def require(
+ requirements: Union[None, _Requirements, Iterable[_Requirements]] = ...,
+ requirements: Union[_E, Iterable[_RequirementsWithE]] = ...,
@@ -0,0 +1,342 @@
+A place for code to be called from the implementation of np.dtype
+String handling is much easier to do correctly in python.
+import numpy as np
+_kind_to_stem = {
+ 'u': 'uint',
+ 'i': 'int',
+ 'c': 'complex',
+ 'f': 'float',
+ 'b': 'bool',
+ 'V': 'void',
+ 'O': 'object',
+ 'M': 'datetime',
+ 'm': 'timedelta',
+ 'S': 'bytes',
+ 'U': 'str',
+def _kind_name(dtype):
+ return _kind_to_stem[dtype.kind]
+ except KeyError as e:
+ raise RuntimeError(
+ "internal dtype error, unknown kind {!r}"
+ .format(dtype.kind)
+ ) from None
+def __str__(dtype):
+ if dtype.fields is not None:
+ return _struct_str(dtype, include_align=True)
+ elif dtype.subdtype:
+ return _subarray_str(dtype)
+ elif issubclass(dtype.type, np.flexible) or not dtype.isnative:
+ return dtype.str
+ return dtype.name
+def __repr__(dtype):
+ arg_str = _construction_repr(dtype, include_align=False)
+ if dtype.isalignedstruct:
+ arg_str = arg_str + ", align=True"
+ return "dtype({})".format(arg_str)
+def _unpack_field(dtype, offset, title=None):
+ Helper function to normalize the items in dtype.fields.
+ Call as:
+ dtype, offset, title = _unpack_field(*dtype.fields[name])
+ return dtype, offset, title
+def _isunsized(dtype):
+ # PyDataType_ISUNSIZED
+ return dtype.itemsize == 0
+def _construction_repr(dtype, include_align=False, short=False):
+ Creates a string repr of the dtype, excluding the 'dtype()' part
+ surrounding the object. This object may be a string, a list, or
+ a dict depending on the nature of the dtype. This
+ is the object passed as the first parameter to the dtype
+ constructor, and if no additional constructor parameters are
+ given, will reproduce the exact memory layout.
+ short : bool
+ If true, this creates a shorter repr using 'kind' and 'itemsize', instead
+ of the longer type name.
+ include_align : bool
+ If true, this includes the 'align=True' parameter
+ inside the struct dtype construction dict when needed. Use this flag
+ if you want a proper repr string without the 'dtype()' part around it.
+ If false, this does not preserve the
+ 'align=True' parameter or sticky NPY_ALIGNED_STRUCT flag for
+ struct arrays like the regular repr does, because the 'align'
+ flag is not part of first dtype constructor parameter. This
+ mode is intended for a full 'repr', where the 'align=True' is
+ provided as the second parameter.
+ return _struct_str(dtype, include_align=include_align)
+ return _scalar_str(dtype, short=short)
+def _scalar_str(dtype, short):
+ byteorder = _byte_order_str(dtype)
+ if dtype.type == np.bool_:
+ if short:
+ return "'?'"
+ return "'bool'"
+ elif dtype.type == np.object_:
+ # The object reference may be different sizes on different
+ # platforms, so it should never include the itemsize here.
+ return "'O'"
+ elif dtype.type == np.string_:
+ if _isunsized(dtype):
+ return "'S'"
+ return "'S%d'" % dtype.itemsize
+ elif dtype.type == np.unicode_:
+ return "'%sU'" % byteorder
+ return "'%sU%d'" % (byteorder, dtype.itemsize / 4)
+ # unlike the other types, subclasses of void are preserved - but
+ # historically the repr does not actually reveal the subclass
+ elif issubclass(dtype.type, np.void):
+ return "'V'"
+ return "'V%d'" % dtype.itemsize
+ elif dtype.type == np.datetime64:
+ return "'%sM8%s'" % (byteorder, _datetime_metadata_str(dtype))
+ elif dtype.type == np.timedelta64:
+ return "'%sm8%s'" % (byteorder, _datetime_metadata_str(dtype))
+ elif np.issubdtype(dtype, np.number):
+ # Short repr with endianness, like '<f8'
+ if short or dtype.byteorder not in ('=', '|'):
+ return "'%s%c%d'" % (byteorder, dtype.kind, dtype.itemsize)
+ # Longer repr, like 'float64'
+ return "'%s%d'" % (_kind_name(dtype), 8*dtype.itemsize)
+ elif dtype.isbuiltin == 2:
+ return dtype.type.__name__
+ "Internal error: NumPy dtype unrecognized type number")
+def _byte_order_str(dtype):
+ """ Normalize byteorder to '<' or '>' """
+ # hack to obtain the native and swapped byte order characters
+ swapped = np.dtype(int).newbyteorder('S')
+ native = swapped.newbyteorder('S')
+ byteorder = dtype.byteorder
+ if byteorder == '=':
+ return native.byteorder
+ if byteorder == 'S':
+ # TODO: this path can never be reached
+ return swapped.byteorder
+ elif byteorder == '|':
+ return ''
+ return byteorder
+def _datetime_metadata_str(dtype):
+ # TODO: this duplicates the C metastr_to_unicode functionality
+ unit, count = np.datetime_data(dtype)
+ if unit == 'generic':
+ elif count == 1:
+ return '[{}]'.format(unit)
+ return '[{}{}]'.format(count, unit)
+def _struct_dict_str(dtype, includealignedflag):
+ # unpack the fields dictionary into ls
+ names = dtype.names
+ fld_dtypes = []
+ offsets = []
+ titles = []
+ for name in names:
+ fld_dtype, offset, title = _unpack_field(*dtype.fields[name])
+ fld_dtypes.append(fld_dtype)
+ offsets.append(offset)
+ titles.append(title)
+ # Build up a string to make the dictionary
+ # First, the names
+ ret = "{'names':["
+ ret += ",".join(repr(name) for name in names)
+ # Second, the formats
+ ret += "], 'formats':["
+ ret += ",".join(
+ _construction_repr(fld_dtype, short=True) for fld_dtype in fld_dtypes)
+ # Third, the offsets
+ ret += "], 'offsets':["
+ ret += ",".join("%d" % offset for offset in offsets)
+ # Fourth, the titles
+ if any(title is not None for title in titles):
+ ret += "], 'titles':["
+ ret += ",".join(repr(title) for title in titles)
+ # Fifth, the itemsize
+ ret += "], 'itemsize':%d" % dtype.itemsize
+ if (includealignedflag and dtype.isalignedstruct):
+ # Finally, the aligned flag
+ ret += ", 'aligned':True}"
+ ret += "}"
+ return ret
+def _is_packed(dtype):
+ Checks whether the structured data type in 'dtype'
+ has a simple layout, where all the fields are in order,
+ and follow each other with no alignment padding.
+ When this returns true, the dtype can be reconstructed
+ from a list of the field names and dtypes with no additional
+ dtype parameters.
+ Duplicates the C `is_dtype_struct_simple_unaligned_layout` function.
+ total_offset = 0
+ for name in dtype.names:
+ fld_dtype, fld_offset, title = _unpack_field(*dtype.fields[name])
+ if fld_offset != total_offset:
+ return False
+ total_offset += fld_dtype.itemsize
+ if total_offset != dtype.itemsize:
+ return True
+def _struct_list_str(dtype):
+ items = []
+ item = "("
+ if title is not None:
+ item += "({!r}, {!r}), ".format(title, name)
+ item += "{!r}, ".format(name)
+ # Special case subarray handling here
+ if fld_dtype.subdtype is not None:
+ base, shape = fld_dtype.subdtype
+ item += "{}, {}".format(
+ _construction_repr(base, short=True),
+ shape
+ item += _construction_repr(fld_dtype, short=True)
+ item += ")"
+ items.append(item)
+ return "[" + ", ".join(items) + "]"
+def _struct_str(dtype, include_align):
+ # The list str representation can't include the 'align=' flag,
+ # so if it is requested and the struct has the aligned flag set,
+ # we must use the dict str instead.
+ if not (include_align and dtype.isalignedstruct) and _is_packed(dtype):
+ sub = _struct_list_str(dtype)
+ sub = _struct_dict_str(dtype, include_align)
+ # If the data type isn't the default, void, show it
+ if dtype.type != np.void:
+ return "({t.__module__}.{t.__name__}, {f})".format(t=dtype.type, f=sub)
+ return sub
+def _subarray_str(dtype):
+ base, shape = dtype.subdtype
+ return "({}, {})".format(
+def _name_includes_bit_suffix(dtype):
+ if dtype.type == np.object_:
+ # pointer size varies by system, best to omit it
+ elif dtype.type == np.bool_:
+ # implied
+ elif np.issubdtype(dtype, np.flexible) and _isunsized(dtype):
+ # unspecified
+def _name_get(dtype):
+ # provides dtype.name.__get__, documented as returning a "bit name"
+ if dtype.isbuiltin == 2:
+ # user dtypes don't promise to do anything special
+ if issubclass(dtype.type, np.void):
+ # historically, void subclasses preserve their name, eg `record64`
+ name = dtype.type.__name__
+ name = _kind_name(dtype)
+ # append bit counts
+ if _name_includes_bit_suffix(dtype):
+ name += "{}".format(dtype.itemsize * 8)
+ # append metadata to datetimes
+ if dtype.type in (np.datetime64, np.timedelta64):
+ name += _datetime_metadata_str(dtype)
+ return name
@@ -0,0 +1,117 @@
+Conversion from ctypes to dtype.
+In an ideal world, we could achieve this through the PEP3118 buffer protocol,
+something like::
+ def dtype_from_ctypes_type(t):
+ # needed to ensure that the shape of `t` is within memoryview.format
+ class DummyStruct(ctypes.Structure):
+ _fields_ = [('a', t)]
+ # empty to avoid memory allocation
+ ctype_0 = (DummyStruct * 0)()
+ mv = memoryview(ctype_0)
+ # convert the struct, and slice back out the field
+ return _dtype_from_pep3118(mv.format)['a']
+Unfortunately, this fails because:
+* ctypes cannot handle length-0 arrays with PEP3118 (bpo-32782)
+* PEP3118 cannot represent unions, but both numpy and ctypes can
+* ctypes cannot handle big-endian structs with PEP3118 (bpo-32780)
+# We delay-import ctypes for distributions that do not include it.
+# While this module is not used unless the user passes in ctypes
+# members, it is eagerly imported from numpy/core/__init__.py.
+def _from_ctypes_array(t):
+ return np.dtype((dtype_from_ctypes_type(t._type_), (t._length_,)))
+def _from_ctypes_structure(t):
+ for item in t._fields_:
+ if len(item) > 2:
+ raise TypeError(
+ "ctypes bitfields have no dtype equivalent")
+ if hasattr(t, "_pack_"):
+ import ctypes
+ formats = []
+ names = []
+ current_offset = 0
+ for fname, ftyp in t._fields_:
+ names.append(fname)
+ formats.append(dtype_from_ctypes_type(ftyp))
+ # Each type has a default offset, this is platform dependent for some types.
+ effective_pack = min(t._pack_, ctypes.alignment(ftyp))
+ current_offset = ((current_offset + effective_pack - 1) // effective_pack) * effective_pack
+ offsets.append(current_offset)
+ current_offset += ctypes.sizeof(ftyp)
+ return np.dtype(dict(
+ formats=formats,
+ offsets=offsets,
+ names=names,
+ itemsize=ctypes.sizeof(t)))
+ fields = []
+ fields.append((fname, dtype_from_ctypes_type(ftyp)))
+ # by default, ctypes structs are aligned
+ return np.dtype(fields, align=True)
+def _from_ctypes_scalar(t):
+ Return the dtype type with endianness included if it's the case
+ if getattr(t, '__ctype_be__', None) is t:
+ return np.dtype('>' + t._type_)
+ elif getattr(t, '__ctype_le__', None) is t:
+ return np.dtype('<' + t._type_)
+ return np.dtype(t._type_)
+def _from_ctypes_union(t):
+ offsets.append(0) # Union fields are offset to 0
+def dtype_from_ctypes_type(t):
+ Construct a dtype object from a ctypes type
+ import _ctypes
+ if issubclass(t, _ctypes.Array):
+ return _from_ctypes_array(t)
+ elif issubclass(t, _ctypes._Pointer):
+ raise TypeError("ctypes pointers have no dtype equivalent")
+ elif issubclass(t, _ctypes.Structure):
+ return _from_ctypes_structure(t)
+ elif issubclass(t, _ctypes.Union):
+ return _from_ctypes_union(t)
+ elif isinstance(getattr(t, '_type_', None), str):
+ return _from_ctypes_scalar(t)
+ raise NotImplementedError(
+ "Unknown ctypes type {}".format(t.__name__))
@@ -0,0 +1,197 @@
+Various richly-typed exceptions, that also help us deal with string formatting
+in python where it's easier.
+By putting the formatting in `__str__`, we also avoid paying the cost for
+users who silence the exceptions.
+from numpy.core.overrides import set_module
+def _unpack_tuple(tup):
+ if len(tup) == 1:
+ return tup[0]
+ return tup
+def _display_as_base(cls):
+ A decorator that makes an exception class look like its base.
+ We use this to hide subclasses that are implementation details - the user
+ should catch the base type, which is what the traceback will show them.
+ Classes decorated with this decorator are subject to removal without a
+ deprecation warning.
+ assert issubclass(cls, Exception)
+ cls.__name__ = cls.__base__.__name__
+ return cls
+class UFuncTypeError(TypeError):
+ """ Base class for all ufunc exceptions """
+ def __init__(self, ufunc):
+ self.ufunc = ufunc
+@_display_as_base
+class _UFuncBinaryResolutionError(UFuncTypeError):
+ """ Thrown when a binary resolution fails """
+ def __init__(self, ufunc, dtypes):
+ super().__init__(ufunc)
+ self.dtypes = tuple(dtypes)
+ assert len(self.dtypes) == 2
+ def __str__(self):
+ return (
+ "ufunc {!r} cannot use operands with types {!r} and {!r}"
+ ).format(
+ self.ufunc.__name__, *self.dtypes
+class _UFuncNoLoopError(UFuncTypeError):
+ """ Thrown when a ufunc loop cannot be found """
+ "ufunc {!r} did not contain a loop with signature matching types "
+ "{!r} -> {!r}"
+ self.ufunc.__name__,
+ _unpack_tuple(self.dtypes[:self.ufunc.nin]),
+ _unpack_tuple(self.dtypes[self.ufunc.nin:])
+class _UFuncCastingError(UFuncTypeError):
+ def __init__(self, ufunc, casting, from_, to):
+ self.casting = casting
+ self.from_ = from_
+ self.to = to
+class _UFuncInputCastingError(_UFuncCastingError):
+ """ Thrown when a ufunc input cannot be casted """
+ def __init__(self, ufunc, casting, from_, to, i):
+ super().__init__(ufunc, casting, from_, to)
+ self.in_i = i
+ # only show the number if more than one input exists
+ i_str = "{} ".format(self.in_i) if self.ufunc.nin != 1 else ""
+ "Cannot cast ufunc {!r} input {}from {!r} to {!r} with casting "
+ "rule {!r}"
+ self.ufunc.__name__, i_str, self.from_, self.to, self.casting
+class _UFuncOutputCastingError(_UFuncCastingError):
+ """ Thrown when a ufunc output cannot be casted """
+ self.out_i = i
+ # only show the number if more than one output exists
+ i_str = "{} ".format(self.out_i) if self.ufunc.nout != 1 else ""
+ "Cannot cast ufunc {!r} output {}from {!r} to {!r} with casting "
+# Exception used in shares_memory()
+class TooHardError(RuntimeError):
+ """ 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
+ # do the string formatting here, to save work in the C code
+ msg = ("axis {} is out of bounds for array of dimension {}"
+ .format(axis, ndim))
+ if msg_prefix is not None:
+ msg = "{}: {}".format(msg_prefix, msg)
+ super(AxisError, self).__init__(msg)
+class _ArrayMemoryError(MemoryError):
+ """ Thrown when an array cannot be allocated"""
+ def __init__(self, shape, dtype):
+ self.shape = shape
+ self.dtype = dtype
+ def _total_size(self):
+ num_bytes = self.dtype.itemsize
+ for dim in self.shape:
+ num_bytes *= dim
+ return num_bytes
+ @staticmethod
+ def _size_to_string(num_bytes):
+ """ Convert a number of bytes into a binary size string """
+ # https://en.wikipedia.org/wiki/Binary_prefix
+ LOG2_STEP = 10
+ STEP = 1024
+ units = ['bytes', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB']
+ unit_i = max(num_bytes.bit_length() - 1, 1) // LOG2_STEP
+ unit_val = 1 << (unit_i * LOG2_STEP)
+ n_units = num_bytes / unit_val
+ del unit_val
+ # ensure we pick a unit that is correct after rounding
+ if round(n_units) == STEP:
+ unit_i += 1
+ n_units /= STEP
+ # deal with sizes so large that we don't have units for them
+ if unit_i >= len(units):
+ new_unit_i = len(units) - 1
+ n_units *= 1 << ((unit_i - new_unit_i) * LOG2_STEP)
+ unit_i = new_unit_i
+ unit_name = units[unit_i]
+ # format with a sensible number of digits
+ if unit_i == 0:
+ # no decimal point on bytes
+ return '{:.0f} {}'.format(n_units, unit_name)
+ elif round(n_units) < 1000:
+ # 3 significant figures, if none are dropped to the left of the .
+ return '{:#.3g} {}'.format(n_units, unit_name)
+ # just give all the digits otherwise
+ return '{:#.0f} {}'.format(n_units, unit_name)
+ size_str = self._size_to_string(self._total_size)
+ "Unable to allocate {} for an array with shape {} and data type {}"
+ .format(size_str, self.shape, self.dtype)
@@ -0,0 +1,873 @@
+A place for internal code
+Some things are more easily handled Python.
+import ast
+import re
+import platform
+from .multiarray import dtype, array, ndarray
+ ctypes = None
+IS_PYPY = platform.python_implementation() == 'PyPy'
+if sys.byteorder == 'little':
+ _nbo = '<'
+ _nbo = '>'
+def _makenames_list(adict, align):
+ allfields = []
+ for fname, obj in adict.items():
+ n = len(obj)
+ if not isinstance(obj, tuple) or n not in (2, 3):
+ raise ValueError("entry not a 2- or 3- tuple")
+ if n > 2 and obj[2] == fname:
+ continue
+ num = int(obj[1])
+ if num < 0:
+ raise ValueError("invalid offset.")
+ format = dtype(obj[0], align=align)
+ if n > 2:
+ title = obj[2]
+ title = None
+ allfields.append((fname, format, num, title))
+ # sort by offsets
+ allfields.sort(key=lambda x: x[2])
+ names = [x[0] for x in allfields]
+ formats = [x[1] for x in allfields]
+ offsets = [x[2] for x in allfields]
+ titles = [x[3] for x in allfields]
+ return names, formats, offsets, titles
+# Called in PyArray_DescrConverter function when
+# a dictionary without "names" and "formats"
+# fields is used as a data-type descriptor.
+def _usefields(adict, align):
+ names = adict[-1]
+ names = None
+ if names is None:
+ names, formats, offsets, titles = _makenames_list(adict, align)
+ res = adict[name]
+ formats.append(res[0])
+ offsets.append(res[1])
+ if len(res) > 2:
+ titles.append(res[2])
+ titles.append(None)
+ return dtype({"names": names,
+ "formats": formats,
+ "offsets": offsets,
+ "titles": titles}, align)
+# construct an array_protocol descriptor list
+# from the fields attribute of a descriptor
+# This calls itself recursively but should eventually hit
+# a descriptor that has no fields and then return
+# a simple typestring
+def _array_descr(descriptor):
+ fields = descriptor.fields
+ if fields is None:
+ subdtype = descriptor.subdtype
+ if subdtype is None:
+ if descriptor.metadata is None:
+ return descriptor.str
+ new = descriptor.metadata.copy()
+ if new:
+ return (descriptor.str, new)
+ return (_array_descr(subdtype[0]), subdtype[1])
+ names = descriptor.names
+ ordered_fields = [fields[x] + (x,) for x in names]
+ result = []
+ offset = 0
+ for field in ordered_fields:
+ if field[1] > offset:
+ num = field[1] - offset
+ result.append(('', f'|V{num}'))
+ offset += num
+ elif field[1] < offset:
+ raise ValueError(
+ "dtype.descr is not defined for types with overlapping or "
+ "out-of-order fields")
+ if len(field) > 3:
+ name = (field[2], field[3])
+ name = field[2]
+ if field[0].subdtype:
+ tup = (name, _array_descr(field[0].subdtype[0]),
+ field[0].subdtype[1])
+ tup = (name, _array_descr(field[0]))
+ offset += field[0].itemsize
+ result.append(tup)
+ if descriptor.itemsize > offset:
+ num = descriptor.itemsize - offset
+ return result
+# Build a new array from the information in a pickle.
+# Note that the name numpy.core._internal._reconstruct is embedded in
+# pickles of ndarrays made with NumPy before release 1.0
+# so don't remove the name here, or you'll
+# break backward compatibility.
+def _reconstruct(subtype, shape, dtype):
+ return ndarray.__new__(subtype, shape, dtype)
+# format_re was originally from numarray by J. Todd Miller
+format_re = re.compile(r'(?P<order1>[<>|=]?)'
+ r'(?P<repeats> *[(]?[ ,0-9]*[)]? *)'
+ r'(?P<order2>[<>|=]?)'
+ r'(?P<dtype>[A-Za-z0-9.?]*(?:\[[a-zA-Z0-9,.]+\])?)')
+sep_re = re.compile(r'\s*,\s*')
+space_re = re.compile(r'\s+$')
+# astr is a string (perhaps comma separated)
+_convorder = {'=': _nbo}
+def _commastring(astr):
+ startindex = 0
+ while startindex < len(astr):
+ mo = format_re.match(astr, pos=startindex)
+ (order1, repeats, order2, dtype) = mo.groups()
+ except (TypeError, AttributeError):
+ f'format number {len(result)+1} of "{astr}" is not recognized'
+ startindex = mo.end()
+ # Separator or ending padding
+ if startindex < len(astr):
+ if space_re.match(astr, pos=startindex):
+ startindex = len(astr)
+ mo = sep_re.match(astr, pos=startindex)
+ if not mo:
+ 'format number %d of "%s" is not recognized' %
+ (len(result)+1, astr))
+ if order2 == '':
+ order = order1
+ elif order1 == '':
+ order = order2
+ order1 = _convorder.get(order1, order1)
+ order2 = _convorder.get(order2, order2)
+ if (order1 != order2):
+ 'inconsistent byte-order specification %s and %s' %
+ (order1, order2))
+ if order in ('|', '=', _nbo):
+ order = ''
+ dtype = order + dtype
+ if (repeats == ''):
+ newitem = dtype
+ newitem = (dtype, ast.literal_eval(repeats))
+ result.append(newitem)
+class dummy_ctype:
+ def __init__(self, cls):
+ self._cls = cls
+ def __mul__(self, other):
+ return self
+ def __call__(self, *other):
+ return self._cls(other)
+ def __eq__(self, other):
+ return self._cls == other._cls
+ def __ne__(self, other):
+ return self._cls != other._cls
+def _getintp_ctype():
+ val = _getintp_ctype.cache
+ if val is not None:
+ if ctypes is None:
+ val = dummy_ctype(np.intp)
+ char = dtype('p').char
+ if char == 'i':
+ val = ctypes.c_int
+ elif char == 'l':
+ val = ctypes.c_long
+ elif char == 'q':
+ val = ctypes.c_longlong
+ _getintp_ctype.cache = val
+_getintp_ctype.cache = None
+# Used for .ctypes attribute of ndarray
+class _missing_ctypes:
+ def cast(self, num, obj):
+ return num.value
+ class c_void_p:
+ def __init__(self, ptr):
+ self.value = ptr
+class _ctypes:
+ def __init__(self, array, ptr=None):
+ self._arr = array
+ if ctypes:
+ self._ctypes = ctypes
+ self._data = self._ctypes.c_void_p(ptr)
+ # fake a pointer-like object that holds onto the reference
+ self._ctypes = _missing_ctypes()
+ self._data._objects = array
+ if self._arr.ndim == 0:
+ self._zerod = True
+ self._zerod = False
+ def data_as(self, obj):
+ Return the data pointer cast to a particular c-types object.
+ For example, calling ``self._as_parameter_`` is equivalent to
+ ``self.data_as(ctypes.c_void_p)``. Perhaps you want to use the data as a
+ pointer to a ctypes array of floating-point data:
+ ``self.data_as(ctypes.POINTER(ctypes.c_double))``.
+ The returned pointer will keep a reference to the array.
+ # _ctypes.cast function causes a circular reference of self._data in
+ # self._data._objects. Attributes of self._data cannot be released
+ # until gc.collect is called. Make a copy of the pointer first then let
+ # it hold the array reference. This is a workaround to circumvent the
+ # CPython bug https://bugs.python.org/issue12836
+ ptr = self._ctypes.cast(self._data, obj)
+ ptr._arr = self._arr
+ return ptr
+ def shape_as(self, obj):
+ Return the shape tuple as an array of some other c-types
+ type. For example: ``self.shape_as(ctypes.c_short)``.
+ if self._zerod:
+ return (obj*self._arr.ndim)(*self._arr.shape)
+ def strides_as(self, obj):
+ Return the strides tuple as an array of some other
+ c-types type. For example: ``self.strides_as(ctypes.c_longlong)``.
+ return (obj*self._arr.ndim)(*self._arr.strides)
+ def data(self):
+ A pointer to the memory area of the array as a Python integer.
+ This memory area may contain data that is not aligned, or not in correct
+ byte-order. The memory area may not even be writeable. The array
+ flags and data-type of this array should be respected when passing this
+ attribute to arbitrary C-code to avoid trouble that can include Python
+ crashing. User Beware! The value of this attribute is exactly the same
+ as ``self._array_interface_['data'][0]``.
+ Note that unlike ``data_as``, a reference will not be kept to the array:
+ code like ``ctypes.c_void_p((a + b).ctypes.data)`` will result in a
+ pointer to a deallocated array, and should be spelt
+ ``(a + b).ctypes.data_as(ctypes.c_void_p)``
+ return self._data.value
+ def shape(self):
+ (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.
+ return self.shape_as(_getintp_ctype())
+ def strides(self):
+ the basetype is the same as for the shape attribute. This ctypes array
+ contains the strides information from the underlying array. This strides
+ information is important for showing how many bytes must be jumped to
+ get to the next element in the array.
+ return self.strides_as(_getintp_ctype())
+ def _as_parameter_(self):
+ Overrides the ctypes semi-magic method
+ Enables `c_func(some_array.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
+def _newnames(datatype, order):
+ Given a datatype and an order object, return a new names tuple, with the
+ order indicated
+ oldnames = datatype.names
+ nameslist = list(oldnames)
+ if isinstance(order, str):
+ order = [order]
+ seen = set()
+ if isinstance(order, (list, tuple)):
+ for name in order:
+ nameslist.remove(name)
+ if name in seen:
+ raise ValueError(f"duplicate field name: {name}") from None
+ raise ValueError(f"unknown field name: {name}") from None
+ seen.add(name)
+ return tuple(list(order) + nameslist)
+ raise ValueError(f"unsupported order value: {order}")
+def _copy_fields(ary):
+ """Return copy of structured array with padding between fields removed.
+ ary : ndarray
+ Structured array from which to remove padding bytes
+ ary_copy : ndarray
+ Copy of ary with padding bytes removed
+ dt = ary.dtype
+ copy_dtype = {'names': dt.names,
+ 'formats': [dt.fields[name][0] for name in dt.names]}
+ return array(ary, dtype=copy_dtype, copy=True)
+def _getfield_is_safe(oldtype, newtype, offset):
+ """ Checks safety of getfield for object arrays.
+ As in _view_is_safe, we need to check that memory containing objects is not
+ reinterpreted as a non-object datatype and vice versa.
+ oldtype : data-type
+ Data type of the original ndarray.
+ newtype : data-type
+ Data type of the field being accessed by ndarray.getfield
+ Offset of the field being accessed by ndarray.getfield
+ If the field access is invalid
+ if newtype.hasobject or oldtype.hasobject:
+ if offset == 0 and newtype == oldtype:
+ return
+ if oldtype.names is not None:
+ for name in oldtype.names:
+ if (oldtype.fields[name][1] == offset and
+ oldtype.fields[name][0] == newtype):
+ raise TypeError("Cannot get/set field of an object array")
+def _view_is_safe(oldtype, newtype):
+ """ Checks safety of a view involving object arrays, for example when
+ doing::
+ np.zeros(10, dtype=oldtype).view(newtype)
+ Data type of original ndarray
+ Data type of the view
+ If the new type is incompatible with the old type.
+ # if the types are equivalent, there is no problem.
+ # for example: dtype((np.record, 'i4,i4')) == dtype((np.void, 'i4,i4'))
+ if oldtype == newtype:
+ raise TypeError("Cannot change data-type for object array.")
+# Given a string containing a PEP 3118 format specifier,
+# construct a NumPy dtype
+_pep3118_native_map = {
+ '?': '?',
+ 'c': 'S1',
+ 'b': 'b',
+ 'B': 'B',
+ 'h': 'h',
+ 'H': 'H',
+ 'i': 'i',
+ 'I': 'I',
+ 'l': 'l',
+ 'L': 'L',
+ 'q': 'q',
+ 'Q': 'Q',
+ 'e': 'e',
+ 'f': 'f',
+ 'd': 'd',
+ 'g': 'g',
+ 'Zf': 'F',
+ 'Zd': 'D',
+ 'Zg': 'G',
+ 's': 'S',
+ 'w': 'U',
+ 'O': 'O',
+ 'x': 'V', # padding
+_pep3118_native_typechars = ''.join(_pep3118_native_map.keys())
+_pep3118_standard_map = {
+ 'h': 'i2',
+ 'H': 'u2',
+ 'i': 'i4',
+ 'I': 'u4',
+ 'l': 'i4',
+ 'L': 'u4',
+ 'q': 'i8',
+ 'Q': 'u8',
+ 'e': 'f2',
+_pep3118_standard_typechars = ''.join(_pep3118_standard_map.keys())
+_pep3118_unsupported_map = {
+ 'u': 'UCS-2 strings',
+ '&': 'pointers',
+ 't': 'bitfields',
+ 'X': 'function pointers',
+class _Stream:
+ def __init__(self, s):
+ self.s = s
+ self.byteorder = '@'
+ def advance(self, n):
+ res = self.s[:n]
+ self.s = self.s[n:]
+ return res
+ def consume(self, c):
+ if self.s[:len(c)] == c:
+ self.advance(len(c))
+ def consume_until(self, c):
+ if callable(c):
+ i = 0
+ while i < len(self.s) and not c(self.s[i]):
+ i = i + 1
+ return self.advance(i)
+ i = self.s.index(c)
+ res = self.advance(i)
+ def next(self):
+ return self.s[0]
+ def __bool__(self):
+ return bool(self.s)
+def _dtype_from_pep3118(spec):
+ stream = _Stream(spec)
+ dtype, align = __dtype_from_pep3118(stream, is_subdtype=False)
+ return dtype
+def __dtype_from_pep3118(stream, is_subdtype):
+ field_spec = dict(
+ names=[],
+ formats=[],
+ offsets=[],
+ itemsize=0
+ common_alignment = 1
+ is_padding = False
+ # Parse spec
+ while stream:
+ value = None
+ # End of structure, bail out to upper level
+ if stream.consume('}'):
+ # Sub-arrays (1)
+ shape = None
+ if stream.consume('('):
+ shape = stream.consume_until(')')
+ shape = tuple(map(int, shape.split(',')))
+ # Byte order
+ if stream.next in ('@', '=', '<', '>', '^', '!'):
+ byteorder = stream.advance(1)
+ if byteorder == '!':
+ byteorder = '>'
+ stream.byteorder = byteorder
+ # Byte order characters also control native vs. standard type sizes
+ if stream.byteorder in ('@', '^'):
+ type_map = _pep3118_native_map
+ type_map_chars = _pep3118_native_typechars
+ type_map = _pep3118_standard_map
+ type_map_chars = _pep3118_standard_typechars
+ # Item sizes
+ itemsize_str = stream.consume_until(lambda c: not c.isdigit())
+ if itemsize_str:
+ itemsize = int(itemsize_str)
+ itemsize = 1
+ # Data types
+ if stream.consume('T{'):
+ value, align = __dtype_from_pep3118(
+ stream, is_subdtype=True)
+ elif stream.next in type_map_chars:
+ if stream.next == 'Z':
+ typechar = stream.advance(2)
+ typechar = stream.advance(1)
+ is_padding = (typechar == 'x')
+ dtypechar = type_map[typechar]
+ if dtypechar in 'USV':
+ dtypechar += '%d' % itemsize
+ numpy_byteorder = {'@': '=', '^': '='}.get(
+ stream.byteorder, stream.byteorder)
+ value = dtype(numpy_byteorder + dtypechar)
+ align = value.alignment
+ elif stream.next in _pep3118_unsupported_map:
+ desc = _pep3118_unsupported_map[stream.next]
+ "Unrepresentable PEP 3118 data type {!r} ({})"
+ .format(stream.next, desc))
+ raise ValueError("Unknown PEP 3118 data type specifier %r" % stream.s)
+ # Native alignment may require padding
+ # Here we assume that the presence of a '@' character implicitly implies
+ # that the start of the array is *already* aligned.
+ extra_offset = 0
+ if stream.byteorder == '@':
+ start_padding = (-offset) % align
+ intra_padding = (-value.itemsize) % align
+ offset += start_padding
+ if intra_padding != 0:
+ if itemsize > 1 or (shape is not None and _prod(shape) > 1):
+ # Inject internal padding to the end of the sub-item
+ value = _add_trailing_padding(value, intra_padding)
+ # We can postpone the injection of internal padding,
+ # as the item appears at most once
+ extra_offset += intra_padding
+ # Update common alignment
+ common_alignment = _lcm(align, common_alignment)
+ # Convert itemsize to sub-array
+ if itemsize != 1:
+ value = dtype((value, (itemsize,)))
+ # Sub-arrays (2)
+ if shape is not None:
+ value = dtype((value, shape))
+ # Field name
+ if stream.consume(':'):
+ name = stream.consume_until(':')
+ name = None
+ if not (is_padding and name is None):
+ if name is not None and name in field_spec['names']:
+ raise RuntimeError(f"Duplicate field name '{name}' in PEP3118 format")
+ field_spec['names'].append(name)
+ field_spec['formats'].append(value)
+ field_spec['offsets'].append(offset)
+ offset += value.itemsize
+ offset += extra_offset
+ field_spec['itemsize'] = offset
+ # extra final padding for aligned types
+ field_spec['itemsize'] += (-offset) % common_alignment
+ # Check if this was a simple 1-item type, and unwrap it
+ if (field_spec['names'] == [None]
+ and field_spec['offsets'][0] == 0
+ and field_spec['itemsize'] == field_spec['formats'][0].itemsize
+ and not is_subdtype):
+ ret = field_spec['formats'][0]
+ _fix_names(field_spec)
+ ret = dtype(field_spec)
+ # Finished
+ return ret, common_alignment
+def _fix_names(field_spec):
+ """ Replace names which are None with the next unused f%d name """
+ names = field_spec['names']
+ for i, name in enumerate(names):
+ if name is not None:
+ j = 0
+ while True:
+ name = f'f{j}'
+ if name not in names:
+ j = j + 1
+ names[i] = name
+def _add_trailing_padding(value, padding):
+ """Inject the specified number of padding bytes at the end of a dtype"""
+ if value.fields is None:
+ names=['f0'],
+ formats=[value],
+ offsets=[0],
+ itemsize=value.itemsize
+ fields = value.fields
+ names = value.names
+ formats=[fields[name][0] for name in names],
+ offsets=[fields[name][1] for name in names],
+ field_spec['itemsize'] += padding
+ return dtype(field_spec)
+def _prod(a):
+ p = 1
+ for x in a:
+ p *= x
+ return p
+def _gcd(a, b):
+ """Calculate the greatest common divisor of a and b"""
+ while b:
+ a, b = b, a % b
+ return a
+def _lcm(a, b):
+ return a // _gcd(a, b) * b
+def array_ufunc_errmsg_formatter(dummy, ufunc, method, *inputs, **kwargs):
+ """ Format the error message for when __array_ufunc__ gives up. """
+ args_string = ', '.join(['{!r}'.format(arg) for arg in inputs] +
+ ['{}={!r}'.format(k, v)
+ for k, v in kwargs.items()])
+ args = inputs + kwargs.get('out', ())
+ types_string = ', '.join(repr(type(arg).__name__) for arg in args)
+ return ('operand type(s) all returned NotImplemented from '
+ '__array_ufunc__({!r}, {!r}, {}): {}'
+ .format(ufunc, method, args_string, types_string))
+def array_function_errmsg_formatter(public_api, types):
+ func_name = '{}.{}'.format(public_api.__module__, public_api.__name__)
+ return ("no implementation found for '{}' on types that implement "
+ '__array_function__: {}'.format(func_name, list(types)))
+def _ufunc_doc_signature_formatter(ufunc):
+ Builds a signature string which resembles PEP 457
+ This is used to construct the first line of the docstring
+ # input arguments are simple
+ if ufunc.nin == 1:
+ in_args = 'x'
+ in_args = ', '.join(f'x{i+1}' for i in range(ufunc.nin))
+ # output arguments are both keyword or positional
+ if ufunc.nout == 0:
+ out_args = ', /, out=()'
+ elif ufunc.nout == 1:
+ out_args = ', /, out=None'
+ out_args = '[, {positional}], / [, out={default}]'.format(
+ positional=', '.join(
+ 'out{}'.format(i+1) for i in range(ufunc.nout)),
+ default=repr((None,)*ufunc.nout)
+ # keyword only args depend on whether this is a gufunc
+ kwargs = (
+ ", casting='same_kind'"
+ ", order='K'"
+ ", dtype=None"
+ ", subok=True"
+ "[, signature"
+ ", extobj]"
+ if ufunc.signature is None:
+ kwargs = ", where=True" + kwargs
+ # join all the parts together
+ return '{name}({in_args}{out_args}, *{kwargs})'.format(
+ name=ufunc.__name__,
+ in_args=in_args,
+ out_args=out_args,
+ kwargs=kwargs
+def npy_ctypes_check(cls):
+ # determine if a class comes from ctypes, in order to work around
+ # a bug in the buffer protocol for those objects, bpo-10746
+ # ctypes class are new-style, so have an __mro__. This probably fails
+ # for ctypes classes with multiple inheritance.
+ # (..., _ctypes.basics._CData, Bufferable, object)
+ ctype_base = cls.__mro__[-3]
+ # # (..., _ctypes._CData, object)
+ ctype_base = cls.__mro__[-2]
+ # right now, they're part of the _ctypes module
+ return '_ctypes' in ctype_base.__module__
+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`:
+ @recursive
+ def stringify(self, arg0, *arg1):
+ return self(*arg1)
+ stringify(*args)
+ def __init__(self, func):
+ self.func = func
+ def __call__(self, *args, **kwargs):
+ return self.func(self, *args, **kwargs)
+from typing import Any
+# TODO: add better annotations when ctypes is stubbed out
+ def data(self) -> int: ...
+ def shape(self) -> Any: ...
+ 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: ...
@@ -0,0 +1,289 @@
+Array methods which are called by both the C-code for the method
+and the Python code for the NumPy-namespace function
+from numpy.core import multiarray as mu
+from numpy.core import umath as um
+from numpy.core._asarray 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
+# save those O(100) nanoseconds!
+umr_maximum = um.maximum.reduce
+umr_minimum = um.minimum.reduce
+umr_sum = um.add.reduce
+umr_prod = um.multiply.reduce
+umr_any = um.logical_or.reduce
+umr_all = um.logical_and.reduce
+# Complex types to -> (2,)float view for fast-path computation in _var()
+_complex_to_float = {
+ nt.dtype(nt.csingle) : nt.dtype(nt.single),
+ nt.dtype(nt.cdouble) : nt.dtype(nt.double),
+# Special case for windows: ensure double takes precedence
+if nt.dtype(nt.longdouble) != nt.dtype(nt.double):
+ _complex_to_float.update({
+ nt.dtype(nt.clongdouble) : nt.dtype(nt.longdouble),
+# avoid keyword arguments to speed up parsing, saves about 15%-20% for very
+# small reductions
+def _amax(a, axis=None, out=None, keepdims=False,
+ initial=_NoValue, where=True):
+ return umr_maximum(a, axis, None, out, keepdims, initial, where)
+def _amin(a, axis=None, out=None, keepdims=False,
+ return umr_minimum(a, axis, None, out, keepdims, initial, where)
+def _sum(a, axis=None, dtype=None, out=None, keepdims=False,
+ return umr_sum(a, axis, dtype, out, keepdims, initial, where)
+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):
+ 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):
+ # fast-path for the default case
+ # no boolean mask given, calculate items according to axis
+ if axis is None:
+ axis = tuple(range(arr.ndim))
+ elif not isinstance(axis, tuple):
+ axis = (axis,)
+ items = nt.intp(1)
+ for ax in axis:
+ items *= arr.shape[mu.normalize_axis_index(ax, arr.ndim)]
+ # TODO: Optimize case when `where` is broadcast along a non-reduction
+ # axis and full sum is more excessive than needed.
+ # guarded to protect circular imports
+ from numpy.lib.stride_tricks import broadcast_to
+ # count True values in (potentially broadcasted) boolean mask
+ items = umr_sum(broadcast_to(where, arr.shape), axis, nt.intp, None,
+ keepdims)
+ return items
+# Numpy 1.17.0, 2019-02-24
+# Various clip behavior deprecations, marked with _clip_dep as a prefix.
+def _clip_dep_is_scalar_nan(a):
+ from numpy.core.fromnumeric import ndim
+ if ndim(a) != 0:
+ return um.isnan(a)
+ except TypeError:
+def _clip_dep_is_byte_swapped(a):
+ if isinstance(a, mu.ndarray):
+ return not a.dtype.isnative
+def _clip_dep_invoke_with_casting(ufunc, *args, out=None, casting=None, **kwargs):
+ # normal path
+ if casting is not None:
+ return ufunc(*args, out=out, casting=casting, **kwargs)
+ # try to deal with broken casting rules
+ return ufunc(*args, out=out, **kwargs)
+ except _exceptions._UFuncOutputCastingError as e:
+ # Numpy 1.17.0, 2019-02-24
+ warnings.warn(
+ "Converting the output of clip from {!r} to {!r} is deprecated. "
+ "Pass `casting=\"unsafe\"` explicitly to silence this warning, or "
+ "correct the type of the variables.".format(e.from_, e.to),
+ DeprecationWarning,
+ stacklevel=2
+ return ufunc(*args, out=out, casting="unsafe", **kwargs)
+def _clip(a, min=None, max=None, out=None, *, casting=None, **kwargs):
+ if min is None and max is None:
+ raise ValueError("One of max or min must be given")
+ # This deprecation probably incurs a substantial slowdown for small arrays,
+ # it will be good to get rid of it.
+ if not _clip_dep_is_byte_swapped(a) and not _clip_dep_is_byte_swapped(out):
+ using_deprecated_nan = False
+ if _clip_dep_is_scalar_nan(min):
+ min = -float('inf')
+ using_deprecated_nan = True
+ if _clip_dep_is_scalar_nan(max):
+ max = float('inf')
+ if using_deprecated_nan:
+ "Passing `np.nan` to mean no clipping in np.clip has always "
+ "been unreliable, and is now deprecated. "
+ "In future, this will always return nan, like it already does "
+ "when min or max are arrays that contain nan. "
+ "To skip a bound, pass either None or an np.inf of an "
+ "appropriate sign.",
+ if min is None:
+ return _clip_dep_invoke_with_casting(
+ um.minimum, a, max, out=out, casting=casting, **kwargs)
+ elif max is None:
+ um.maximum, a, min, out=out, casting=casting, **kwargs)
+ um.clip, a, min, max, out=out, casting=casting, **kwargs)
+def _mean(a, axis=None, dtype=None, out=None, keepdims=False, *, where=True):
+ arr = asanyarray(a)
+ is_float16_result = False
+ rcount = _count_reduce_items(arr, axis, keepdims=keepdims, where=where)
+ 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
+ if dtype is None:
+ if issubclass(arr.dtype.type, (nt.integer, nt.bool_)):
+ dtype = mu.dtype('f8')
+ elif issubclass(arr.dtype.type, nt.float16):
+ dtype = mu.dtype('f4')
+ is_float16_result = True
+ ret = umr_sum(arr, axis, dtype, out, keepdims, where=where)
+ if isinstance(ret, mu.ndarray):
+ ret = um.true_divide(
+ ret, rcount, out=ret, casting='unsafe', subok=False)
+ if is_float16_result and out is None:
+ ret = arr.dtype.type(ret)
+ elif hasattr(ret, 'dtype'):
+ if is_float16_result:
+ ret = arr.dtype.type(ret / rcount)
+ ret = ret.dtype.type(ret / rcount)
+ ret = ret / rcount
+def _var(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False, *,
+ where=True):
+ # Make this warning show up on top.
+ 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)
+ if dtype is None and issubclass(arr.dtype.type, (nt.integer, nt.bool_)):
+ # Compute the mean.
+ # Note that if dtype is not of inexact type then arraymean will
+ # not be either.
+ arrmean = umr_sum(arr, axis, dtype, keepdims=True, where=where)
+ # The shape of rcount has to match arrmean to not change the shape of out
+ # in broadcasting. Otherwise, it cannot be stored back to arrmean.
+ if rcount.ndim == 0:
+ # fast-path for default case when where is True
+ div = rcount
+ # matching rcount to arrmean when where is specified as array
+ div = rcount.reshape(arrmean.shape)
+ if isinstance(arrmean, mu.ndarray):
+ arrmean = um.true_divide(arrmean, div, out=arrmean, casting='unsafe',
+ subok=False)
+ arrmean = arrmean.dtype.type(arrmean / rcount)
+ # Compute sum of squared deviations from mean
+ # Note that x may not be inexact and that we need it to be an array,
+ # not a scalar.
+ x = asanyarray(arr - arrmean)
+ if issubclass(arr.dtype.type, (nt.floating, nt.integer)):
+ x = um.multiply(x, x, out=x)
+ # Fast-paths for built-in complex types
+ elif x.dtype in _complex_to_float:
+ xv = x.view(dtype=(_complex_to_float[x.dtype], (2,)))
+ um.multiply(xv, xv, out=xv)
+ x = um.add(xv[..., 0], xv[..., 1], out=x.real).real
+ # Most general case; includes handling object arrays containing imaginary
+ # numbers and complex types with non-native byteorder
+ x = um.multiply(x, um.conjugate(x), out=x).real
+ ret = umr_sum(x, axis, dtype, out, keepdims=keepdims, where=where)
+ # Compute degrees of freedom and make sure it is not negative.
+ rcount = um.maximum(rcount - ddof, 0)
+ # divide by degrees of freedom
+def _std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False, *,
+ ret = _var(a, axis=axis, dtype=dtype, out=out, ddof=ddof,
+ keepdims=keepdims, where=where)
+ ret = um.sqrt(ret, out=ret)
+ ret = ret.dtype.type(um.sqrt(ret))
+ ret = um.sqrt(ret)
+def _ptp(a, axis=None, out=None, keepdims=False):
+ return um.subtract(
+ umr_maximum(a, axis, None, out, keepdims),
+ umr_minimum(a, axis, None, None, keepdims),
+ out
+def _dump(self, file, protocol=2):
+ if hasattr(file, 'write'):
+ ctx = contextlib_nullcontext(file)
+ ctx = open(os_fspath(file), "wb")
+ with ctx as f:
+ pickle.dump(self, f, protocol=protocol)
+def _dumps(self, protocol=2):
+ return pickle.dumps(self, protocol=protocol)
@@ -0,0 +1,100 @@
+String-handling utilities to avoid locale-dependence.
+Used primarily to generate type name aliases.
+# "import string" is costly to import!
+# Construct the translation tables directly
+# "A" = chr(65), "a" = chr(97)
+_all_chars = [chr(_m) for _m in range(256)]
+_ascii_upper = _all_chars[65:65+26]
+_ascii_lower = _all_chars[97:97+26]
+LOWER_TABLE = "".join(_all_chars[:65] + _ascii_lower + _all_chars[65+26:])
+UPPER_TABLE = "".join(_all_chars[:97] + _ascii_upper + _all_chars[97+26:])
+def english_lower(s):
+ """ Apply English case rules to convert ASCII strings to all lower case.
+ This is an internal utility function to replace calls to str.lower() such
+ that we can avoid changing behavior with changing locales. In particular,
+ Turkish has distinct dotted and dotless variants of the Latin letter "I" in
+ both lowercase and uppercase. Thus, "I".lower() != "i" in a "tr" locale.
+ s : str
+ lowered : str
+ >>> from numpy.core.numerictypes import english_lower
+ >>> english_lower('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_')
+ 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789_'
+ >>> english_lower('')
+ ''
+ lowered = s.translate(LOWER_TABLE)
+ return lowered
+def english_upper(s):
+ """ Apply English case rules to convert ASCII strings to all upper case.
+ This is an internal utility function to replace calls to str.upper() such
+ both lowercase and uppercase. Thus, "i".upper() != "I" in a "tr" locale.
+ uppered : str
+ >>> from numpy.core.numerictypes import english_upper
+ >>> english_upper('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_')
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_'
+ >>> english_upper('')
+ uppered = s.translate(UPPER_TABLE)
+ return uppered
+def english_capitalize(s):
+ """ Apply English case rules to convert the first character of an ASCII
+ string to upper case.
+ This is an internal utility function to replace calls to str.capitalize()
+ such that we can avoid changing behavior with changing locales.
+ capitalized : str
+ >>> from numpy.core.numerictypes import english_capitalize
+ >>> english_capitalize('int8')
+ 'Int8'
+ >>> english_capitalize('Int8')
+ >>> english_capitalize('')
+ if s:
+ return english_upper(s[0]) + s[1:]
@@ -0,0 +1,243 @@
+Due to compatibility, numpy has a very large number of different naming
+conventions for the scalar types (those subclassing from `numpy.generic`).
+This file produces a convoluted set of dictionaries mapping names to types,
+and sometimes other mappings too.
+.. data:: allTypes
+ A dictionary of names to types that will be exposed as attributes through
+ ``np.core.numerictypes.*``
+.. data:: sctypeDict
+ Similar to `allTypes`, but maps a broader set of aliases to their types.
+.. data:: sctypes
+ A dictionary keyed by a "type group" string, providing a list of types
+ under that group.
+from numpy.compat import unicode
+from numpy.core._string_helpers import english_lower
+from numpy.core.multiarray import typeinfo, dtype
+from numpy.core._dtype import _kind_name
+sctypeDict = {} # Contains all leaf-node scalar types with aliases
+allTypes = {} # Collect the types we will add to the module
+# separate the actual type info from the abstract base classes
+_abstract_types = {}
+_concrete_typeinfo = {}
+for k, v in typeinfo.items():
+ # make all the keys lowercase too
+ k = english_lower(k)
+ if isinstance(v, type):
+ _abstract_types[k] = v
+ _concrete_typeinfo[k] = v
+_concrete_types = {v.type for k, v in _concrete_typeinfo.items()}
+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")
+ # some third-party type - make a best-guess
+ return dtype(obj).itemsize * 8
+ return info.bits
+def bitname(obj):
+ """Return a bit-width name for a given type object"""
+ bits = _bits_of(obj)
+ dt = dtype(obj)
+ char = dt.kind
+ base = _kind_name(dt)
+ if base == 'object':
+ bits = 0
+ if bits != 0:
+ char = "%s%d" % (char, bits // 8)
+ return base, bits, char
+def _add_types():
+ for name, info in _concrete_typeinfo.items():
+ # define C-name and insert typenum and typechar references also
+ allTypes[name] = info.type
+ sctypeDict[name] = info.type
+ sctypeDict[info.char] = info.type
+ sctypeDict[info.num] = info.type
+ for name, cls in _abstract_types.items():
+ allTypes[name] = cls
+_add_types()
+# This is the priority order used to assign the bit-sized NPY_INTxx names, which
+# must match the order in npy_common.h in order for NPY_INTxx and np.intxx to be
+# consistent.
+# If two C types have the same size, then the earliest one in this list is used
+# as the sized name.
+_int_ctypes = ['long', 'longlong', 'int', 'short', 'byte']
+_uint_ctypes = list('u' + t for t in _int_ctypes)
+def _add_aliases():
+ # these are handled by _add_integer_aliases
+ if name in _int_ctypes or name in _uint_ctypes:
+ # insert bit-width version for this class (if relevant)
+ base, bit, char = bitname(info.type)
+ myname = "%s%d" % (base, bit)
+ # ensure that (c)longdouble does not overwrite the aliases assigned to
+ # (c)double
+ if name in ('longdouble', 'clongdouble') and myname in allTypes:
+ allTypes[myname] = info.type
+ # add mapping for both the bit name and the numarray name
+ sctypeDict[myname] = info.type
+ # add forward, reverse, and string mapping to numarray
+ sctypeDict[char] = info.type
+ # Add deprecated numeric-style type aliases manually, at some point
+ # we may want to deprecate the lower case "bytes0" version as well.
+ for name in ["Bytes0", "Datetime64", "Str0", "Uint32", "Uint64"]:
+ if english_lower(name) not in allTypes:
+ # Only one of Uint32 or Uint64, aliases of `np.uintp`, was (and is) defined, note that this
+ # is not UInt32/UInt64 (capital i), which is removed.
+ allTypes[name] = allTypes[english_lower(name)]
+ sctypeDict[name] = sctypeDict[english_lower(name)]
+_add_aliases()
+def _add_integer_aliases():
+ seen_bits = set()
+ for i_ctype, u_ctype in zip(_int_ctypes, _uint_ctypes):
+ i_info = _concrete_typeinfo[i_ctype]
+ u_info = _concrete_typeinfo[u_ctype]
+ bits = i_info.bits # same for both
+ for info, charname, intname in [
+ (i_info,'i%d' % (bits//8,), 'int%d' % bits),
+ (u_info,'u%d' % (bits//8,), 'uint%d' % bits)]:
+ if bits not in seen_bits:
+ # sometimes two different types have the same number of bits
+ # if so, the one iterated over first takes precedence
+ allTypes[intname] = info.type
+ sctypeDict[intname] = info.type
+ sctypeDict[charname] = info.type
+ seen_bits.add(bits)
+_add_integer_aliases()
+# We use these later
+void = allTypes['void']
+# Rework the Python names (so that float and complex and int are consistent
+# with Python usage)
+def _set_up_aliases():
+ type_pairs = [('complex_', 'cdouble'),
+ ('int0', 'intp'),
+ ('uint0', 'uintp'),
+ ('single', 'float'),
+ ('csingle', 'cfloat'),
+ ('singlecomplex', 'cfloat'),
+ ('float_', 'double'),
+ ('intc', 'int'),
+ ('uintc', 'uint'),
+ ('int_', 'long'),
+ ('uint', 'ulong'),
+ ('cfloat', 'cdouble'),
+ ('longfloat', 'longdouble'),
+ ('clongfloat', 'clongdouble'),
+ ('longcomplex', 'clongdouble'),
+ ('bool_', 'bool'),
+ ('bytes_', 'string'),
+ ('string_', 'string'),
+ ('str_', 'unicode'),
+ ('unicode_', 'unicode'),
+ ('object_', 'object')]
+ for alias, t in type_pairs:
+ allTypes[alias] = allTypes[t]
+ sctypeDict[alias] = sctypeDict[t]
+ # Remove aliases overriding python types and modules
+ to_remove = ['ulong', 'object', 'int', 'float',
+ 'complex', 'bool', 'string', 'datetime', 'timedelta',
+ 'bytes', 'str']
+ for t in to_remove:
+ del allTypes[t]
+ del sctypeDict[t]
+_set_up_aliases()
+sctypes = {'int': [],
+ 'uint':[],
+ 'float':[],
+ 'complex':[],
+ 'others':[bool, object, bytes, unicode, void]}
+def _add_array_type(typename, bits):
+ t = allTypes['%s%d' % (typename, bits)]
+ sctypes[typename].append(t)
+def _set_array_types():
+ ibytes = [1, 2, 4, 8, 16, 32, 64]
+ fbytes = [2, 4, 8, 10, 12, 16, 32, 64]
+ for bytes in ibytes:
+ bits = 8*bytes
+ _add_array_type('int', bits)
+ _add_array_type('uint', bits)
+ for bytes in fbytes:
+ _add_array_type('float', bits)
+ _add_array_type('complex', 2*bits)
+ _gi = dtype('p')
+ if _gi.type not in sctypes['int']:
+ indx = 0
+ sz = _gi.itemsize
+ _lst = sctypes['int']
+ while (indx < len(_lst) and sz >= _lst[indx](0).itemsize):
+ indx += 1
+ sctypes['int'].insert(indx, _gi.type)
+ sctypes['uint'].insert(indx, dtype('P').type)
+_set_array_types()
+# Add additional strings to the sctypeDict
+_toadd = ['int', 'float', 'complex', 'bool', 'object',
+ 'str', 'bytes', ('a', 'bytes_')]
+for name in _toadd:
+ if isinstance(name, tuple):
+ sctypeDict[name[0]] = allTypes[name[1]]
+ sctypeDict[name] = allTypes['%s_' % name]
+del _toadd, name
+from typing import Dict, Union, Type, List
+from numpy import generic, signedinteger, unsignedinteger, floating, complexfloating
+ from typing import TypedDict
+ from typing_extensions import TypedDict
+class _SCTypes(TypedDict):
+ int: List[Type[signedinteger]]
+ uint: List[Type[unsignedinteger]]
+ float: List[Type[floating]]
+ complex: List[Type[complexfloating]]
+ others: List[type]
+sctypeDict: Dict[Union[int, str], Type[generic]]
+sctypes: _SCTypes
@@ -0,0 +1,450 @@
+Functions for changing global ufunc configuration
+This provides helpers which wrap `umath.geterrobj` and `umath.seterrobj`
+import collections.abc
+import contextlib
+from .overrides import set_module
+from .umath import (
+ UFUNC_BUFSIZE_DEFAULT,
+ ERR_IGNORE, ERR_WARN, ERR_RAISE, ERR_CALL, ERR_PRINT, ERR_LOG, ERR_DEFAULT,
+ SHIFT_DIVIDEBYZERO, SHIFT_OVERFLOW, SHIFT_UNDERFLOW, SHIFT_INVALID,
+ "seterr", "geterr", "setbufsize", "getbufsize", "seterrcall", "geterrcall",
+ "errstate",
+_errdict = {"ignore": ERR_IGNORE,
+ "warn": ERR_WARN,
+ "raise": ERR_RAISE,
+ "call": ERR_CALL,
+ "print": ERR_PRINT,
+ "log": ERR_LOG}
+_errdict_rev = {value: key for key, value in _errdict.items()}
+def seterr(all=None, divide=None, over=None, under=None, invalid=None):
+ Set how floating-point errors are handled.
+ Note that operations on integer scalar types (such as `int16`) are
+ handled like floating point, and are affected by these settings.
+ all : {'ignore', 'warn', 'raise', 'call', 'print', 'log'}, optional
+ Set treatment for all types of floating-point errors at once:
+ - ignore: Take no action when the exception occurs.
+ - warn: Print a `RuntimeWarning` (via the Python `warnings` module).
+ - raise: Raise a `FloatingPointError`.
+ - call: Call a function specified using the `seterrcall` function.
+ - print: Print a warning directly to ``stdout``.
+ - log: Record error in a Log object specified by `seterrcall`.
+ The default is not to change the current behavior.
+ divide : {'ignore', 'warn', 'raise', 'call', 'print', 'log'}, optional
+ Treatment for division by zero.
+ over : {'ignore', 'warn', 'raise', 'call', 'print', 'log'}, optional
+ Treatment for floating-point overflow.
+ under : {'ignore', 'warn', 'raise', 'call', 'print', 'log'}, optional
+ Treatment for floating-point underflow.
+ invalid : {'ignore', 'warn', 'raise', 'call', 'print', 'log'}, optional
+ Treatment for invalid floating-point operation.
+ old_settings : dict
+ Dictionary containing the old settings.
+ seterrcall : Set a callback function for the 'call' mode.
+ geterr, geterrcall, errstate
+ The floating-point exceptions are defined in the IEEE 754 standard [1]_:
+ - Division by zero: infinite result obtained from finite numbers.
+ - Overflow: result too large to be expressed.
+ - Underflow: result so close to zero that some precision
+ was lost.
+ - Invalid operation: result is not an expressible number, typically
+ indicates that a NaN was produced.
+ .. [1] https://en.wikipedia.org/wiki/IEEE_754
+ >>> old_settings = np.seterr(all='ignore') #seterr to known value
+ >>> np.seterr(over='raise')
+ {'divide': 'ignore', 'over': 'ignore', 'under': 'ignore', 'invalid': 'ignore'}
+ >>> np.seterr(**old_settings) # reset to default
+ {'divide': 'ignore', 'over': 'raise', 'under': 'ignore', 'invalid': 'ignore'}
+ >>> np.int16(32000) * np.int16(3)
+ 30464
+ >>> old_settings = np.seterr(all='warn', over='raise')
+ 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')])
+ pyvals = umath.geterrobj()
+ old = geterr()
+ if divide is None:
+ divide = all or old['divide']
+ if over is None:
+ over = all or old['over']
+ if under is None:
+ under = all or old['under']
+ if invalid is None:
+ invalid = all or old['invalid']
+ maskvalue = ((_errdict[divide] << SHIFT_DIVIDEBYZERO) +
+ (_errdict[over] << SHIFT_OVERFLOW) +
+ (_errdict[under] << SHIFT_UNDERFLOW) +
+ (_errdict[invalid] << SHIFT_INVALID))
+ pyvals[1] = maskvalue
+ umath.seterrobj(pyvals)
+ return old
+def geterr():
+ Get the current way of handling floating-point errors.
+ res : dict
+ A dictionary with keys "divide", "over", "under", and "invalid",
+ whose values are from the strings "ignore", "print", "log", "warn",
+ "raise", and "call". The keys represent possible floating-point
+ exceptions, and the values define how these exceptions are handled.
+ geterrcall, seterr, seterrcall
+ >>> sorted(np.geterr().items())
+ [('divide', 'warn'), ('invalid', 'warn'), ('over', 'warn'), ('under', 'ignore')]
+ >>> 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')])
+ maskvalue = umath.geterrobj()[1]
+ mask = 7
+ res = {}
+ val = (maskvalue >> SHIFT_DIVIDEBYZERO) & mask
+ res['divide'] = _errdict_rev[val]
+ val = (maskvalue >> SHIFT_OVERFLOW) & mask
+ res['over'] = _errdict_rev[val]
+ val = (maskvalue >> SHIFT_UNDERFLOW) & mask
+ res['under'] = _errdict_rev[val]
+ val = (maskvalue >> SHIFT_INVALID) & mask
+ res['invalid'] = _errdict_rev[val]
+def setbufsize(size):
+ Set the size of the buffer used in ufuncs.
+ Size of buffer.
+ if size > 10e6:
+ raise ValueError("Buffer size, %s, is too big." % size)
+ if size < 5:
+ raise ValueError("Buffer size, %s, is too small." % size)
+ if size % 16 != 0:
+ raise ValueError("Buffer size, %s, is not a multiple of 16." % size)
+ old = getbufsize()
+ pyvals[0] = size
+def getbufsize():
+ Return the size of the buffer used in ufuncs.
+ getbufsize : int
+ Size of ufunc buffer in bytes.
+ return umath.geterrobj()[0]
+def seterrcall(func):
+ Set the floating-point error callback function or log object.
+ There are two ways to capture floating-point error messages. The first
+ is to set the error-handler to 'call', using `seterr`. Then, set
+ the function to call using this function.
+ The second is to set the error-handler to 'log', using `seterr`.
+ Floating-point errors then trigger a call to the 'write' method of
+ the provided object.
+ func : callable f(err, flag) or object with write method
+ Function to call upon floating-point errors ('call'-mode) or
+ object whose 'write' method is used to log such message ('log'-mode).
+ The call function takes two arguments. The first is a string describing
+ the type of error (such as "divide by zero", "overflow", "underflow",
+ or "invalid value"), and the second is the status flag. The flag is a
+ byte, whose four least-significant bits indicate the type of error, one
+ of "divide", "over", "under", "invalid"::
+ [0 0 0 0 divide over under invalid]
+ In other words, ``flags = divide + 2*over + 4*under + 8*invalid``.
+ If an object is provided, its write method should take one argument,
+ a string.
+ h : callable, log instance or None
+ The old error handler.
+ seterr, geterr, geterrcall
+ Callback upon error:
+ >>> saved_handler = np.seterrcall(err_handler)
+ >>> save_err = np.seterr(all='call')
+ >>> np.array([1, 2, 3]) / 0.0
+ Floating point error (divide by zero), with flag 1
+ array([inf, inf, inf])
+ >>> 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')])
+ Log error message:
+ >>> class Log:
+ ... def write(self, msg):
+ ... print("LOG: %s" % msg)
+ >>> log = Log()
+ >>> saved_handler = np.seterrcall(log)
+ >>> save_err = np.seterr(all='log')
+ LOG: Warning: divide by zero encountered in true_divide
+ <numpy.core.numeric.Log object at 0x...>
+ OrderedDict([('divide', 'log'), ('invalid', 'log'), ('over', 'log'), ('under', 'log')])
+ if func is not None and not isinstance(func, collections.abc.Callable):
+ if (not hasattr(func, 'write') or
+ not isinstance(func.write, collections.abc.Callable)):
+ raise ValueError("Only callable can be used as callback")
+ old = geterrcall()
+ pyvals[2] = func
+def geterrcall():
+ Return the current callback function used on floating-point errors.
+ When the error handling for a floating-point error (one of "divide",
+ "over", "under", or "invalid") is set to 'call' or 'log', the function
+ that is called or the log instance that is written to is returned by
+ `geterrcall`. This function or log instance has been set with
+ `seterrcall`.
+ errobj : callable, log instance or None
+ The current error handler. If no handler was set through `seterrcall`,
+ ``None`` is returned.
+ seterrcall, seterr, geterr
+ >>> np.geterrcall() # we did not yet set a handler, returns None
+ >>> oldsettings = np.seterr(all='call')
+ >>> oldhandler = np.seterrcall(err_handler)
+ >>> cur_handler = np.geterrcall()
+ >>> cur_handler is err_handler
+ return umath.geterrobj()[2]
+class _unspecified:
+_Unspecified = _unspecified()
+class errstate(contextlib.ContextDecorator):
+ errstate(**kwargs)
+ Context manager for floating-point error handling.
+ Using an instance of `errstate` as a context manager allows statements in
+ that context to execute with a known error handling behavior. Upon entering
+ the context the error handling is set with `seterr` and `seterrcall`, and
+ upon exiting it is reset to what it was before.
+ `errstate` is also usable as a function decorator, saving
+ a level of indentation if an entire function is wrapped.
+ See :py:class:`contextlib.ContextDecorator` for more information.
+ kwargs : {divide, over, under, invalid}
+ Keyword arguments. The valid keywords are the possible floating-point
+ exceptions. Each keyword should have a string value that defines the
+ treatment for the particular error. Possible values are
+ {'ignore', 'warn', 'raise', 'call', 'print', 'log'}.
+ seterr, geterr, seterrcall, geterrcall
+ >>> olderr = np.seterr(all='ignore') # Set error handling to known state.
+ >>> np.arange(3) / 0.
+ array([nan, inf, inf])
+ >>> with np.errstate(divide='warn'):
+ ... np.arange(3) / 0.
+ >>> np.sqrt(-1)
+ nan
+ >>> with np.errstate(invalid='raise'):
+ ... np.sqrt(-1)
+ File "<stdin>", line 2, in <module>
+ FloatingPointError: invalid value encountered in sqrt
+ Outside the context the error handling behavior has not changed:
+ OrderedDict([('divide', 'ignore'), ('invalid', 'ignore'), ('over', 'ignore'), ('under', 'ignore')])
+ def __init__(self, *, call=_Unspecified, **kwargs):
+ self.call = call
+ self.kwargs = kwargs
+ self.oldstate = seterr(**self.kwargs)
+ if self.call is not _Unspecified:
+ self.oldcall = seterrcall(self.call)
+ def __exit__(self, *exc_info):
+ seterr(**self.oldstate)
+ seterrcall(self.oldcall)
+def _setdef():
+ defval = [UFUNC_BUFSIZE_DEFAULT, ERR_DEFAULT, None]
+ umath.seterrobj(defval)
+# set the default values
+_setdef()
@@ -0,0 +1,43 @@
+from typing import Optional, Union, Callable, Any
+ from typing import Literal, Protocol, TypedDict
+ from typing_extensions import Literal, Protocol, TypedDict
+_ErrKind = Literal["ignore", "warn", "raise", "call", "print", "log"]
+_ErrFunc = Callable[[str, int], Any]
+class _SupportsWrite(Protocol):
+ def write(self, __msg: str) -> Any: ...
+class _ErrDict(TypedDict):
+ divide: _ErrKind
+ over: _ErrKind
+ under: _ErrKind
+ invalid: _ErrKind
+class _ErrDictOptional(TypedDict, total=False):
+ all: Optional[_ErrKind]
+ divide: Optional[_ErrKind]
+ over: Optional[_ErrKind]
+ under: Optional[_ErrKind]
+ invalid: Optional[_ErrKind]
+def seterr(
+) -> _ErrDict: ...
+def geterr() -> _ErrDict: ...
+def setbufsize(size: int) -> int: ...
+def getbufsize() -> int: ...
+def seterrcall(
+ func: Union[None, _ErrFunc, _SupportsWrite]
+) -> Union[None, _ErrFunc, _SupportsWrite]: ...
+def geterrcall() -> Union[None, _ErrFunc, _SupportsWrite]: ...
+# See `numpy/__init__.pyi` for the `errstate` class
@@ -0,0 +1,1630 @@
+"""Array printing function
+$Id: arrayprint.py,v 1.9 2005/09/13 13:58:44 teoliphant Exp $
+__all__ = ["array2string", "array_str", "array_repr", "set_string_function",
+ "set_printoptions", "get_printoptions", "printoptions",
+ "format_float_positional", "format_float_scientific"]
+__docformat__ = 'restructuredtext'
+# Written by Konrad Hinsen <hinsenk@ere.umontreal.ca>
+# last revision: 1996-3-13
+# modified by Jim Hugunin 1997-3-3 for repr's and str's (and other details)
+# and by Perry Greenfield 2000-4-1 for numarray
+# and by Travis Oliphant 2005-8-22 for numpy
+# Note: Both scalartypes.c.src and arrayprint.py implement strs for numpy
+# scalars but for different purposes. scalartypes.c.src has str/reprs for when
+# the scalar is printed on its own, while arrayprint.py has strs for when
+# scalars are printed inside an ndarray. Only the latter strs are currently
+# user-customizable.
+import functools
+import numbers
+ from _thread import get_ident
+ from _dummy_thread import get_ident
+from . import numerictypes as _nt
+from .umath import absolute, isinf, isfinite, isnat
+from . import multiarray
+from .multiarray import (array, dragon4_positional, dragon4_scientific,
+ datetime_as_string, datetime_data, ndarray,
+ set_legacy_print_mode)
+from .fromnumeric import any
+from .numeric import concatenate, asarray, errstate
+from .numerictypes import (longlong, intc, int_, float_, complex_, bool_,
+ flexible)
+from .overrides import array_function_dispatch, set_module
+_format_options = {
+ 'edgeitems': 3, # repr N leading and trailing items of each dimension
+ 'threshold': 1000, # total items > triggers array summarization
+ 'floatmode': 'maxprec',
+ 'precision': 8, # precision of floating point representations
+ 'suppress': False, # suppress printing small floating values in exp format
+ 'linewidth': 75,
+ 'nanstr': 'nan',
+ 'infstr': 'inf',
+ 'sign': '-',
+ 'formatter': None,
+ 'legacy': False}
+def _make_options_dict(precision=None, threshold=None, edgeitems=None,
+ linewidth=None, suppress=None, nanstr=None, infstr=None,
+ sign=None, formatter=None, floatmode=None, legacy=None):
+ """ make a dictionary out of the non-None arguments, plus sanity checks """
+ options = {k: v for k, v in locals().items() if v is not None}
+ if suppress is not None:
+ options['suppress'] = bool(suppress)
+ modes = ['fixed', 'unique', 'maxprec', 'maxprec_equal']
+ if floatmode not in modes + [None]:
+ raise ValueError("floatmode option must be one of " +
+ ", ".join('"{}"'.format(m) for m in modes))
+ if sign not in [None, '-', '+', ' ']:
+ raise ValueError("sign option must be one of ' ', '+', or '-'")
+ 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):
+ raise TypeError("threshold must be numeric")
+ if np.isnan(threshold):
+ raise ValueError("threshold must be non-NAN, try "
+ "sys.maxsize for untruncated representation")
+ return options
+def set_printoptions(precision=None, threshold=None, edgeitems=None,
+ formatter=None, sign=None, floatmode=None, *, legacy=None):
+ Set printing options.
+ These options determine the way floating point numbers, arrays and
+ other NumPy objects are displayed.
+ precision : int or None, optional
+ Number of digits of precision for floating point output (default 8).
+ May be None if `floatmode` is not `fixed`, to print as many digits as
+ necessary to uniquely specify the value.
+ threshold : int, optional
+ Total number of array elements which trigger summarization
+ rather than full repr (default 1000).
+ To always use the full repr without summarization, pass `sys.maxsize`.
+ edgeitems : int, optional
+ Number of array items in summary at beginning and end of
+ each dimension (default 3).
+ linewidth : int, optional
+ The number of characters per line for the purpose of inserting
+ line breaks (default 75).
+ suppress : bool, optional
+ If True, always print floating point numbers using fixed point
+ notation, in which case numbers equal to zero in the current precision
+ will print as zero. If False, then scientific notation is used when
+ absolute value of the smallest number is < 1e-4 or the ratio of the
+ maximum absolute value to the minimum is > 1e3. The default is False.
+ nanstr : str, optional
+ String representation of floating point not-a-number (default nan).
+ infstr : str, optional
+ String representation of floating point infinity (default inf).
+ sign : string, either '-', '+', or ' ', optional
+ Controls printing of the sign of floating-point types. If '+', always
+ print the sign of positive values. If ' ', always prints a space
+ (whitespace character) in the sign position of positive values. If
+ '-', omit the sign character of positive values. (default '-')
+ formatter : dict of callables, optional
+ If not None, the keys should indicate the type(s) that the respective
+ formatting function applies to. Callables should return a string.
+ Types that are not specified (by their corresponding keys) are handled
+ by the default formatters. Individual types for which a formatter
+ can be set are:
+ - 'bool'
+ - 'int'
+ - 'timedelta' : a `numpy.timedelta64`
+ - 'datetime' : a `numpy.datetime64`
+ - 'float'
+ - 'longfloat' : 128-bit floats
+ - 'complexfloat'
+ - '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:
+ - 'all' : sets all types
+ - 'int_kind' : sets 'int'
+ - 'float_kind' : sets 'float' and 'longfloat'
+ - 'complex_kind' : sets 'complexfloat' and 'longcomplexfloat'
+ - 'str_kind' : sets 'str' and 'numpystr'
+ floatmode : str, optional
+ Controls the interpretation of the `precision` option for
+ floating-point types. Can take the following values
+ (default maxprec_equal):
+ * 'fixed': Always print exactly `precision` fractional digits,
+ even if this would print more or fewer digits than
+ necessary to specify the value uniquely.
+ * 'unique': Print the minimum number of fractional digits necessary
+ to represent each value uniquely. Different elements may
+ have a different number of digits. The value of the
+ `precision` option is ignored.
+ * 'maxprec': Print at most `precision` fractional digits, but if
+ an element can be uniquely represented with fewer digits
+ only print it with that many.
+ * 'maxprec_equal': Print at most `precision` fractional digits,
+ but if every element in the array can be uniquely
+ represented with an equal number of fewer digits, use that
+ many digits for all elements.
+ legacy : string or `False`, optional
+ If set to the string `'1.13'` enables 1.13 legacy printing mode. This
+ approximates numpy 1.13 print output by including a space in the sign
+ position of floats and different behavior for 0d arrays. If set to
+ `False`, disables legacy mode. Unrecognized strings will be ignored
+ with a warning for forward compatibility.
+ .. versionadded:: 1.14.0
+ get_printoptions, printoptions, set_string_function, array2string
+ `formatter` is always reset with a call to `set_printoptions`.
+ Use `printoptions` as a context manager to set the values temporarily.
+ Floating point precision can be set:
+ >>> np.set_printoptions(precision=4)
+ >>> np.array([1.123456789])
+ [1.1235]
+ Long arrays can be summarised:
+ >>> np.set_printoptions(threshold=5)
+ >>> np.arange(10)
+ array([0, 1, 2, ..., 7, 8, 9])
+ Small results can be suppressed:
+ >>> eps = np.finfo(float).eps
+ >>> x = np.arange(4.)
+ >>> x**2 - (x + eps)**2
+ array([-4.9304e-32, -4.4409e-16, 0.0000e+00, 0.0000e+00])
+ >>> np.set_printoptions(suppress=True)
+ array([-0., -0., 0., 0.])
+ A custom formatter can be used to display array elements as desired:
+ >>> np.set_printoptions(formatter={'all':lambda x: 'int: '+str(-x)})
+ >>> x = np.arange(3)
+ array([int: 0, int: -1, int: -2])
+ >>> np.set_printoptions() # formatter gets reset
+ To put back the default options, you can use:
+ >>> np.set_printoptions(edgeitems=3, infstr='inf',
+ ... linewidth=75, nanstr='nan', precision=8,
+ ... suppress=False, threshold=1000, formatter=None)
+ Also to temporarily override options, use `printoptions` as a context manager:
+ >>> with np.printoptions(precision=2, suppress=True, threshold=5):
+ ... np.linspace(0, 10, 10)
+ array([ 0. , 1.11, 2.22, ..., 7.78, 8.89, 10. ])
+ opt = _make_options_dict(precision, threshold, edgeitems, linewidth,
+ suppress, nanstr, infstr, sign, formatter,
+ floatmode, legacy)
+ # formatter is always reset
+ opt['formatter'] = formatter
+ _format_options.update(opt)
+ # set the C variable for legacy mode
+ if _format_options['legacy'] == '1.13':
+ set_legacy_print_mode(113)
+ # reset the sign option in legacy mode to avoid confusion
+ _format_options['sign'] = '-'
+ elif _format_options['legacy'] is False:
+ set_legacy_print_mode(0)
+def get_printoptions():
+ Return the current print options.
+ print_opts : dict
+ Dictionary of current print options with keys
+ - precision : int
+ - threshold : int
+ - edgeitems : int
+ - linewidth : int
+ - suppress : bool
+ - nanstr : str
+ - infstr : str
+ - formatter : dict of callables
+ - sign : str
+ For a full description of these options, see `set_printoptions`.
+ set_printoptions, printoptions, set_string_function
+ return _format_options.copy()
+@contextlib.contextmanager
+def printoptions(*args, **kwargs):
+ """Context manager for setting print options.
+ Set print options for the scope of the `with` block, and restore the old
+ options at the end. See `set_printoptions` for the full description of
+ available options.
+ >>> from numpy.testing import assert_equal
+ >>> with np.printoptions(precision=2):
+ ... np.array([2.0]) / 3
+ array([0.67])
+ The `as`-clause of the `with`-statement gives the current print options:
+ >>> with np.printoptions(precision=2) as opts:
+ ... assert_equal(opts, np.get_printoptions())
+ set_printoptions, get_printoptions
+ opts = np.get_printoptions()
+ np.set_printoptions(*args, **kwargs)
+ yield np.get_printoptions()
+ finally:
+ np.set_printoptions(**opts)
+def _leading_trailing(a, edgeitems, index=()):
+ Keep only the N-D corners (leading and trailing edges) of an array.
+ Should be passed a base-class ndarray, since it makes no guarantees about
+ preserving subclasses.
+ axis = len(index)
+ if axis == a.ndim:
+ return a[index]
+ if a.shape[axis] > 2*edgeitems:
+ return concatenate((
+ _leading_trailing(a, edgeitems, index + np.index_exp[ :edgeitems]),
+ _leading_trailing(a, edgeitems, index + np.index_exp[-edgeitems:])
+ ), axis=axis)
+ return _leading_trailing(a, edgeitems, index + np.index_exp[:])
+def _object_format(o):
+ """ Object arrays containing lists should be printed unambiguously """
+ if type(o) is list:
+ fmt = 'list({!r})'
+ fmt = '{!r}'
+ return fmt.format(o)
+def repr_format(x):
+ return repr(x)
+def str_format(x):
+ return str(x)
+def _get_formatdict(data, *, precision, floatmode, suppress, sign, legacy,
+ formatter, **kwargs):
+ # note: extra arguments in kwargs are ignored
+ # wrapped in lambdas to avoid taking a code path with the wrong type of data
+ formatdict = {
+ 'bool': lambda: BoolFormat(data),
+ 'int': lambda: IntegerFormat(data),
+ 'float': lambda: FloatingFormat(
+ data, precision, floatmode, suppress, sign, legacy=legacy),
+ 'longfloat': lambda: FloatingFormat(
+ 'complexfloat': lambda: ComplexFloatingFormat(
+ 'longcomplexfloat': lambda: ComplexFloatingFormat(
+ 'datetime': lambda: DatetimeFormat(data, legacy=legacy),
+ 'timedelta': lambda: TimedeltaFormat(data),
+ 'object': lambda: _object_format,
+ 'void': lambda: str_format,
+ 'numpystr': lambda: repr_format,
+ 'str': lambda: str}
+ # we need to wrap values in `formatter` in a lambda, so that the interface
+ # is the same as the above values.
+ def indirect(x):
+ return lambda: x
+ if formatter is not None:
+ fkeys = [k for k in formatter.keys() if formatter[k] is not None]
+ if 'all' in fkeys:
+ for key in formatdict.keys():
+ formatdict[key] = indirect(formatter['all'])
+ if 'int_kind' in fkeys:
+ for key in ['int']:
+ formatdict[key] = indirect(formatter['int_kind'])
+ if 'float_kind' in fkeys:
+ for key in ['float', 'longfloat']:
+ formatdict[key] = indirect(formatter['float_kind'])
+ if 'complex_kind' in fkeys:
+ 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'])
+ if key in fkeys:
+ formatdict[key] = indirect(formatter[key])
+ return formatdict
+def _get_format_function(data, **options):
+ find the right formatting function for the dtype_
+ dtype_ = data.dtype
+ dtypeobj = dtype_.type
+ formatdict = _get_formatdict(data, **options)
+ if issubclass(dtypeobj, _nt.bool_):
+ return formatdict['bool']()
+ elif issubclass(dtypeobj, _nt.integer):
+ if issubclass(dtypeobj, _nt.timedelta64):
+ return formatdict['timedelta']()
+ return formatdict['int']()
+ elif issubclass(dtypeobj, _nt.floating):
+ if issubclass(dtypeobj, _nt.longfloat):
+ return formatdict['longfloat']()
+ return formatdict['float']()
+ elif issubclass(dtypeobj, _nt.complexfloating):
+ if issubclass(dtypeobj, _nt.clongfloat):
+ return formatdict['longcomplexfloat']()
+ return formatdict['complexfloat']()
+ elif issubclass(dtypeobj, (_nt.unicode_, _nt.string_)):
+ return formatdict['numpystr']()
+ elif issubclass(dtypeobj, _nt.datetime64):
+ return formatdict['datetime']()
+ elif issubclass(dtypeobj, _nt.object_):
+ return formatdict['object']()
+ elif issubclass(dtypeobj, _nt.void):
+ if dtype_.names is not None:
+ return StructuredVoidFormat.from_data(data, **options)
+ return formatdict['void']()
+def _recursive_guard(fillvalue='...'):
+ Like the python 3.2 reprlib.recursive_repr, but forwards *args and **kwargs
+ Decorates a function such that if it calls itself with the same first
+ argument, it returns `fillvalue` instead of recursing.
+ Largely copied from reprlib.recursive_repr
+ def decorating_function(f):
+ repr_running = set()
+ @functools.wraps(f)
+ def wrapper(self, *args, **kwargs):
+ key = id(self), get_ident()
+ if key in repr_running:
+ return fillvalue
+ repr_running.add(key)
+ return f(self, *args, **kwargs)
+ repr_running.discard(key)
+ return wrapper
+ return decorating_function
+# gracefully handle recursive calls, when object arrays contain themselves
+@_recursive_guard()
+def _array2string(a, options, separator=' ', prefix=""):
+ # The formatter __init__s in _get_format_function cannot deal with
+ # subclasses yet, and we also need to avoid recursion issues in
+ # _formatArray with subclasses which return 0d arrays in place of scalars
+ data = asarray(a)
+ if a.shape == ():
+ a = data
+ if a.size > options['threshold']:
+ summary_insert = "..."
+ data = _leading_trailing(data, options['edgeitems'])
+ summary_insert = ""
+ # find the right formatting function for the array
+ format_function = _get_format_function(data, **options)
+ # skip over "["
+ next_line_prefix = " "
+ # skip over array(
+ next_line_prefix += " "*len(prefix)
+ lst = _formatArray(a, format_function, options['linewidth'],
+ next_line_prefix, separator, options['edgeitems'],
+ summary_insert, options['legacy'])
+ return lst
+def _array2string_dispatcher(
+ a, max_line_width=None, precision=None,
+ suppress_small=None, separator=None, prefix=None,
+ style=None, formatter=None, threshold=None,
+ edgeitems=None, sign=None, floatmode=None, suffix=None,
+ *, legacy=None):
+ return (a,)
+@array_function_dispatch(_array2string_dispatcher, module='numpy')
+def array2string(a, max_line_width=None, precision=None,
+ suppress_small=None, separator=' ', prefix="",
+ style=np._NoValue, formatter=None, threshold=None,
+ edgeitems=None, sign=None, floatmode=None, suffix="",
+ Return a string representation of an array.
+ max_line_width : int, optional
+ Inserts newlines if text is longer than `max_line_width`.
+ Defaults to ``numpy.get_printoptions()['linewidth']``.
+ Floating point precision.
+ Defaults to ``numpy.get_printoptions()['precision']``.
+ suppress_small : bool, optional
+ Represent numbers "very close" to zero as zero; default is False.
+ Very close is defined by precision: if the precision is 8, e.g.,
+ numbers smaller (in absolute value) than 5e-9 are represented as
+ zero.
+ Defaults to ``numpy.get_printoptions()['suppress']``.
+ separator : str, optional
+ Inserted between elements.
+ prefix : 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::
+ prefix + array2string(a) + suffix
+ The output is left-padded by the length of the prefix string, and
+ wrapping is forced at the column ``max_line_width - len(suffix)``.
+ It should be noted that the content of prefix and suffix strings are
+ not included in the output.
+ style : _NoValue, optional
+ Has no effect, do not use.
+ .. deprecated:: 1.14.0
+ - 'void' : type `numpy.void`
+ rather than full repr.
+ Defaults to ``numpy.get_printoptions()['threshold']``.
+ each dimension.
+ Defaults to ``numpy.get_printoptions()['edgeitems']``.
+ '-', omit the sign character of positive values.
+ Defaults to ``numpy.get_printoptions()['sign']``.
+ floating-point types.
+ Defaults to ``numpy.get_printoptions()['floatmode']``.
+ Can take the following values:
+ - 'fixed': Always print exactly `precision` fractional digits,
+ - 'unique': Print the minimum number of fractional digits necessary
+ - 'maxprec': Print at most `precision` fractional digits, but if
+ - 'maxprec_equal': Print at most `precision` fractional digits,
+ array_str : str
+ String representation of the array.
+ if a callable in `formatter` does not return a string.
+ array_str, array_repr, set_printoptions, get_printoptions
+ If a formatter is specified for a certain type, the `precision` keyword is
+ ignored for that type.
+ This is a very flexible function; `array_repr` and `array_str` are using
+ `array2string` internally so keywords with the same name should work
+ identically in all three functions.
+ >>> x = np.array([1e-16,1,2,3])
+ >>> np.array2string(x, precision=2, separator=',',
+ ... suppress_small=True)
+ '[0.,1.,2.,3.]'
+ >>> x = np.arange(3.)
+ >>> np.array2string(x, formatter={'float_kind':lambda x: "%.2f" % x})
+ '[0.00 1.00 2.00]'
+ >>> np.array2string(x, formatter={'int':lambda x: hex(x)})
+ '[0x0 0x1 0x2]'
+ overrides = _make_options_dict(precision, threshold, edgeitems,
+ max_line_width, suppress_small, None, None,
+ sign, formatter, floatmode, legacy)
+ options = _format_options.copy()
+ options.update(overrides)
+ if options['legacy'] == '1.13':
+ if style is np._NoValue:
+ style = repr
+ if a.shape == () and a.dtype.names is None:
+ return style(a.item())
+ elif style is not np._NoValue:
+ # Deprecation 11-9-2017 v1.14
+ warnings.warn("'style' argument is deprecated and no longer functional"
+ " except in 1.13 'legacy' mode",
+ DeprecationWarning, stacklevel=3)
+ if options['legacy'] != '1.13':
+ options['linewidth'] -= len(suffix)
+ # treat as a null array if any of shape elements == 0
+ if a.size == 0:
+ return "[]"
+ return _array2string(a, options, separator, prefix)
+def _extendLine(s, line, word, line_width, next_line_prefix, legacy):
+ needs_wrap = len(line) + len(word) > line_width
+ if legacy != '1.13':
+ # don't wrap lines if it won't help
+ if len(line) <= len(next_line_prefix):
+ needs_wrap = False
+ if needs_wrap:
+ s += line.rstrip() + "\n"
+ line = next_line_prefix
+ line += word
+ return s, line
+def _extendLine_pretty(s, line, word, line_width, next_line_prefix, legacy):
+ Extends line with nicely formatted (possibly multi-line) string ``word``.
+ words = word.splitlines()
+ if len(words) == 1 or legacy == '1.13':
+ return _extendLine(s, line, word, line_width, next_line_prefix, legacy)
+ max_word_length = max(len(word) for word in words)
+ if (len(line) + max_word_length > line_width and
+ len(line) > len(next_line_prefix)):
+ s += line.rstrip() + '\n'
+ line = next_line_prefix + words[0]
+ indent = next_line_prefix
+ indent = len(line)*' '
+ line += words[0]
+ for word in words[1::]:
+ line = indent + word
+ suffix_length = max_word_length - len(words[-1])
+ line += suffix_length*' '
+def _formatArray(a, format_function, line_width, next_line_prefix,
+ separator, edge_items, summary_insert, legacy):
+ """formatArray is designed for two modes of operation:
+ 1. Full output
+ 2. Summarized output
+ def recurser(index, hanging_indent, curr_width):
+ By using this local function, we don't need to recurse with all the
+ arguments. Since this function is not created recursively, the cost is
+ not significant
+ axes_left = a.ndim - axis
+ if axes_left == 0:
+ return format_function(a[index])
+ # when recursing, add a space to align with the [ added, and reduce the
+ # length of the line by 1
+ next_hanging_indent = hanging_indent + ' '
+ if legacy == '1.13':
+ next_width = curr_width
+ next_width = curr_width - len(']')
+ a_len = a.shape[axis]
+ show_summary = summary_insert and 2*edge_items < a_len
+ if show_summary:
+ leading_items = edge_items
+ trailing_items = edge_items
+ leading_items = 0
+ trailing_items = a_len
+ # stringify the array with the hanging indent on the first line too
+ s = ''
+ # last axis (rows) - wrap elements if they would not fit on one line
+ if axes_left == 1:
+ # the length up until the beginning of the separator / bracket
+ elem_width = curr_width - len(separator.rstrip())
+ elem_width = curr_width - max(len(separator.rstrip()), len(']'))
+ line = hanging_indent
+ for i in range(leading_items):
+ word = recurser(index + (i,), next_hanging_indent, next_width)
+ s, line = _extendLine_pretty(
+ s, line, word, elem_width, hanging_indent, legacy)
+ line += separator
+ s, line = _extendLine(
+ s, line, summary_insert, elem_width, hanging_indent, legacy)
+ line += ", "
+ for i in range(trailing_items, 1, -1):
+ word = recurser(index + (-i,), next_hanging_indent, next_width)
+ # width of the separator is not considered on 1.13
+ elem_width = curr_width
+ word = recurser(index + (-1,), next_hanging_indent, next_width)
+ s += line
+ # other axes - insert newlines between rows
+ line_sep = separator.rstrip() + '\n'*(axes_left - 1)
+ nested = recurser(index + (i,), next_hanging_indent, next_width)
+ s += hanging_indent + nested + line_sep
+ # trailing space, fixed nbr of newlines, and fixed separator
+ s += hanging_indent + summary_insert + ", \n"
+ s += hanging_indent + summary_insert + line_sep
+ nested = recurser(index + (-i,), next_hanging_indent,
+ next_width)
+ nested = recurser(index + (-1,), next_hanging_indent, next_width)
+ s += hanging_indent + nested
+ # remove the hanging indent, and wrap in []
+ s = '[' + s[len(hanging_indent):] + ']'
+ # invoke the recursive part with an initial index and prefix
+ return recurser(index=(),
+ hanging_indent=next_line_prefix,
+ curr_width=line_width)
+ # recursive closures have a cyclic reference to themselves, which
+ # requires gc to collect (gh-10620). To avoid this problem, for
+ # performance and PyPy friendliness, we break the cycle:
+ recurser = None
+def _none_or_positive_arg(x, name):
+ if x is None:
+ return -1
+ if x < 0:
+ raise ValueError("{} must be >= 0".format(name))
+ return x
+class FloatingFormat:
+ """ Formatter for subtypes of np.floating """
+ def __init__(self, data, precision, floatmode, suppress_small, sign=False,
+ # for backcompatibility, accept bools
+ if isinstance(sign, bool):
+ sign = '+' if sign else '-'
+ self._legacy = legacy
+ if self._legacy == '1.13':
+ # when not 0d, legacy does not support '-'
+ if data.shape != () and sign == '-':
+ sign = ' '
+ self.floatmode = floatmode
+ if floatmode == 'unique':
+ self.precision = None
+ self.precision = precision
+ self.precision = _none_or_positive_arg(self.precision, 'precision')
+ self.suppress_small = suppress_small
+ self.sign = sign
+ self.exp_format = False
+ self.large_exponent = False
+ self.fillFormat(data)
+ def fillFormat(self, data):
+ # only the finite values are used to compute the number of digits
+ finite_vals = data[isfinite(data)]
+ # choose exponential mode based on the non-zero finite values:
+ abs_non_zero = absolute(finite_vals[finite_vals != 0])
+ if len(abs_non_zero) != 0:
+ max_val = np.max(abs_non_zero)
+ min_val = np.min(abs_non_zero)
+ with errstate(over='ignore'): # division can overflow
+ if max_val >= 1.e8 or (not self.suppress_small and
+ (min_val < 0.0001 or max_val/min_val > 1000.)):
+ self.exp_format = True
+ # do a first pass of printing all the numbers, to determine sizes
+ if len(finite_vals) == 0:
+ self.pad_left = 0
+ self.pad_right = 0
+ self.trim = '.'
+ self.exp_size = -1
+ self.unique = True
+ elif self.exp_format:
+ trim, unique = '.', True
+ if self.floatmode == 'fixed' or self._legacy == '1.13':
+ trim, unique = 'k', False
+ strs = (dragon4_scientific(x, precision=self.precision,
+ unique=unique, trim=trim, sign=self.sign == '+')
+ for x in finite_vals)
+ frac_strs, _, exp_strs = zip(*(s.partition('e') for s in strs))
+ int_part, frac_part = zip(*(s.split('.') for s in frac_strs))
+ self.exp_size = max(len(s) for s in exp_strs) - 1
+ self.trim = 'k'
+ self.precision = max(len(s) for s in frac_part)
+ # for back-compat with np 1.13, use 2 spaces & sign and full prec
+ self.pad_left = 3
+ # this should be only 1 or 2. Can be calculated from sign.
+ 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
+ # first pass printing to determine sizes
+ if self.floatmode == 'fixed':
+ strs = (dragon4_positional(x, precision=self.precision,
+ fractional=True,
+ unique=unique, trim=trim,
+ sign=self.sign == '+')
+ int_part, frac_part = zip(*(s.split('.') for s in strs))
+ self.pad_left = 1 + max(len(s.lstrip('-+')) for s in int_part)
+ self.pad_right = max(len(s) for s in frac_part)
+ if self.floatmode in ['fixed', 'maxprec_equal']:
+ self.precision = self.pad_right
+ if self._legacy != '1.13':
+ # account for sign = ' ' by adding one to pad_left
+ if self.sign == ' ' and not any(np.signbit(finite_vals)):
+ self.pad_left += 1
+ # if there are non-finite values, may need to increase pad_left
+ if data.size != finite_vals.size:
+ neginf = self.sign != '-' or any(data[isinf(data)] < 0)
+ nanlen = len(_format_options['nanstr'])
+ inflen = len(_format_options['infstr']) + neginf
+ offset = self.pad_right + 1 # +1 for decimal pt
+ self.pad_left = max(self.pad_left, nanlen - offset, inflen - offset)
+ def __call__(self, x):
+ if not np.isfinite(x):
+ with errstate(invalid='ignore'):
+ if np.isnan(x):
+ sign = '+' if self.sign == '+' else ''
+ ret = sign + _format_options['nanstr']
+ else: # isinf
+ sign = '-' if x < 0 else '+' if self.sign == '+' else ''
+ ret = sign + _format_options['infstr']
+ return ' '*(self.pad_left + self.pad_right + 1 - len(ret)) + ret
+ if self.exp_format:
+ return dragon4_scientific(x,
+ precision=self.precision,
+ unique=self.unique,
+ trim=self.trim,
+ sign=self.sign == '+',
+ pad_left=self.pad_left,
+ exp_digits=self.exp_size)
+ return dragon4_positional(x,
+ pad_right=self.pad_right)
+def format_float_scientific(x, precision=None, unique=True, trim='k',
+ sign=False, pad_left=None, exp_digits=None):
+ Format a floating-point scalar as a decimal string in scientific notation.
+ Provides control over rounding, trimming and padding. Uses and assumes
+ IEEE unbiased rounding. Uses the "Dragon4" algorithm.
+ x : python float or numpy floating scalar
+ precision : non-negative integer or None, optional
+ Maximum number of digits to print. May be None if `unique` is
+ `True`, but must be an integer if unique is `False`.
+ unique : boolean, optional
+ 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.
+ If `False`, digits are generated as if printing an infinite-precision
+ value and stopping after `precision` digits, rounding the remaining
+ trim : one of 'k', '.', '0', '-', optional
+ Controls post-processing trimming of trailing digits, as follows:
+ * 'k' : keep trailing zeros, keep decimal point (no trimming)
+ * '.' : trim all trailing zeros, leave decimal point
+ * '0' : trim all but the zero before the decimal point. Insert the
+ zero if it is missing.
+ * '-' : trim trailing zeros and any trailing decimal point
+ sign : boolean, optional
+ Whether to show the sign for positive values.
+ pad_left : non-negative integer, optional
+ Pad the left side of the string with whitespace until at least that
+ many characters are to the left of the decimal point.
+ 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.
+ >>> np.format_float_scientific(np.float32(np.pi))
+ '3.1415927e+00'
+ >>> s = np.float32(1.23e24)
+ >>> np.format_float_scientific(s, unique=False, precision=15)
+ '1.230000071797338e+24'
+ >>> np.format_float_scientific(s, exp_digits=4)
+ '1.23e+0024'
+ 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')
+ return dragon4_scientific(x, precision=precision, unique=unique,
+ trim=trim, sign=sign, pad_left=pad_left,
+ exp_digits=exp_digits)
+def format_float_positional(x, precision=None, unique=True,
+ fractional=True, trim='k', sign=False,
+ pad_left=None, pad_right=None):
+ Format a floating-point scalar as a decimal string in positional notation.
+ was omitted, print out all necessary digits, otherwise digit generation
+ is cut off after `precision` digits and the remaining value is rounded.
+ 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.
+ 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.
+ >>> np.format_float_positional(np.float32(np.pi))
+ '3.1415927'
+ >>> np.format_float_positional(np.float16(np.pi))
+ '3.14'
+ >>> np.format_float_positional(np.float16(0.3))
+ '0.3'
+ >>> np.format_float_positional(np.float16(0.3), unique=False, precision=10)
+ '0.3000488281'
+ pad_right = _none_or_positive_arg(pad_right, 'pad_right')
+ return dragon4_positional(x, precision=precision, unique=unique,
+ fractional=fractional, trim=trim,
+ sign=sign, pad_left=pad_left,
+ pad_right=pad_right)
+class IntegerFormat:
+ def __init__(self, data):
+ if data.size > 0:
+ max_str_len = max(len(str(np.max(data))),
+ len(str(np.min(data))))
+ max_str_len = 0
+ self.format = '%{}d'.format(max_str_len)
+ return self.format % x
+class BoolFormat:
+ def __init__(self, data, **kwargs):
+ # add an extra space so " True" and "False" have the same length and
+ # array elements align nicely when printed, except in 0d arrays
+ self.truestr = ' True' if data.shape != () else 'True'
+ return self.truestr if x else "False"
+class ComplexFloatingFormat:
+ """ Formatter for subtypes of np.complexfloating """
+ def __init__(self, x, precision, floatmode, suppress_small,
+ sign=False, *, legacy=None):
+ floatmode_real = floatmode_imag = floatmode
+ floatmode_real = 'maxprec_equal'
+ floatmode_imag = 'maxprec'
+ self.real_format = FloatingFormat(
+ x.real, precision, floatmode_real, suppress_small,
+ sign=sign, legacy=legacy
+ self.imag_format = FloatingFormat(
+ x.imag, precision, floatmode_imag, suppress_small,
+ sign='+', legacy=legacy
+ r = self.real_format(x.real)
+ i = self.imag_format(x.imag)
+ # add the 'j' before the terminal whitespace in i
+ sp = len(i.rstrip())
+ i = i[:sp] + 'j' + i[sp:]
+ return r + i
+class _TimelikeFormat:
+ non_nat = data[~isnat(data)]
+ if len(non_nat) > 0:
+ # Max str length of non-NaT elements
+ max_str_len = max(len(self._format_non_nat(np.max(non_nat))),
+ len(self._format_non_nat(np.min(non_nat))))
+ if len(non_nat) < data.size:
+ # data contains a NaT
+ max_str_len = max(max_str_len, 5)
+ self._format = '%{}s'.format(max_str_len)
+ self._nat = "'NaT'".rjust(max_str_len)
+ def _format_non_nat(self, x):
+ # override in subclass
+ raise NotImplementedError
+ if isnat(x):
+ return self._nat
+ return self._format % self._format_non_nat(x)
+class DatetimeFormat(_TimelikeFormat):
+ def __init__(self, x, unit=None, timezone=None, casting='same_kind',
+ legacy=False):
+ # Get the unit from the dtype
+ if unit is None:
+ if x.dtype.kind == 'M':
+ unit = datetime_data(x.dtype)[0]
+ unit = 's'
+ if timezone is None:
+ timezone = 'naive'
+ self.timezone = timezone
+ self.unit = unit
+ self.legacy = legacy
+ # must be called after the above are configured
+ super(DatetimeFormat, self).__init__(x)
+ if self.legacy == '1.13':
+ return self._format_non_nat(x)
+ return super(DatetimeFormat, self).__call__(x)
+ return "'%s'" % datetime_as_string(x,
+ unit=self.unit,
+ timezone=self.timezone,
+ casting=self.casting)
+class TimedeltaFormat(_TimelikeFormat):
+ return str(x.astype('i8'))
+class SubArrayFormat:
+ def __init__(self, format_function):
+ self.format_function = format_function
+ def __call__(self, arr):
+ if arr.ndim <= 1:
+ return "[" + ", ".join(self.format_function(a) for a in arr) + "]"
+ return "[" + ", ".join(self.__call__(a) for a in arr) + "]"
+class StructuredVoidFormat:
+ Formatter for structured np.void objects.
+ This does not work on structured alias types like np.dtype(('i4', 'i2,i2')),
+ as alias scalars lose their field information, and the implementation
+ relies upon np.void.__getitem__.
+ def __init__(self, format_functions):
+ self.format_functions = format_functions
+ @classmethod
+ def from_data(cls, data, **options):
+ This is a second way to initialize StructuredVoidFormat, using the raw data
+ as input. Added to avoid changing the signature of __init__.
+ format_functions = []
+ for field_name in data.dtype.names:
+ format_function = _get_format_function(data[field_name], **options)
+ if data.dtype[field_name].shape != ():
+ format_function = SubArrayFormat(format_function)
+ format_functions.append(format_function)
+ return cls(format_functions)
+ str_fields = [
+ format_function(field)
+ for field, format_function in zip(x, self.format_functions)
+ if len(str_fields) == 1:
+ return "({},)".format(str_fields[0])
+ return "({})".format(", ".join(str_fields))
+def _void_scalar_repr(x):
+ Implements the repr for structured-void scalars. It is called from the
+ scalartypes.c.src code, and is placed here because it uses the elementwise
+ formatters defined above.
+ return StructuredVoidFormat.from_data(array(x), **_format_options)(x)
+_typelessdata = [int_, float_, complex_, bool_]
+if issubclass(intc, int):
+ _typelessdata.append(intc)
+if issubclass(longlong, int):
+ _typelessdata.append(longlong)
+def dtype_is_implied(dtype):
+ Determine if the given dtype is implied by the representation of its values.
+ Data type
+ implied : bool
+ True if the dtype is implied by the representation of its values.
+ >>> np.core.arrayprint.dtype_is_implied(int)
+ >>> np.array([1, 2, 3], int)
+ >>> np.core.arrayprint.dtype_is_implied(np.int8)
+ >>> np.array([1, 2, 3], np.int8)
+ array([1, 2, 3], dtype=int8)
+ dtype = np.dtype(dtype)
+ if _format_options['legacy'] == '1.13' and dtype.type == bool_:
+ # not just void types can be structured, and names are not part of the repr
+ if dtype.names is not None:
+ return dtype.type in _typelessdata
+def dtype_short_repr(dtype):
+ Convert a dtype to a short form which evaluates to the same dtype.
+ The intent is roughly that the following holds
+ >>> from numpy import *
+ >>> dt = np.int64([1, 2]).dtype
+ >>> assert eval(dtype_short_repr(dt)) == dt
+ # structured dtypes give a list or tuple repr
+ return str(dtype)
+ elif issubclass(dtype.type, flexible):
+ # handle these separately so they don't give garbage like str256
+ return "'%s'" % str(dtype)
+ typename = dtype.name
+ # quote typenames which can't be represented as python variable names
+ if typename and not (typename[0].isalpha() and typename.isalnum()):
+ typename = repr(typename)
+ return typename
+def _array_repr_implementation(
+ arr, max_line_width=None, precision=None, suppress_small=None,
+ array2string=array2string):
+ """Internal version of array_repr() that allows overriding array2string."""
+ if max_line_width is None:
+ max_line_width = _format_options['linewidth']
+ if type(arr) is not ndarray:
+ class_name = type(arr).__name__
+ class_name = "array"
+ skipdtype = dtype_is_implied(arr.dtype) and arr.size > 0
+ prefix = class_name + "("
+ suffix = ")" if skipdtype else ","
+ if (_format_options['legacy'] == '1.13' and
+ arr.shape == () and not arr.dtype.names):
+ lst = repr(arr.item())
+ elif arr.size > 0 or arr.shape == (0,):
+ lst = array2string(arr, max_line_width, precision, suppress_small,
+ ', ', prefix, suffix=suffix)
+ else: # show zero-length shape unless it is (0,)
+ lst = "[], shape=%s" % (repr(arr.shape),)
+ arr_str = prefix + lst + suffix
+ if skipdtype:
+ return arr_str
+ dtype_str = "dtype={})".format(dtype_short_repr(arr.dtype))
+ # compute whether we should put dtype on a new line: Do so if adding the
+ # dtype would extend the last line past max_line_width.
+ # Note: This line gives the correct result even when rfind returns -1.
+ last_line_len = len(arr_str) - (arr_str.rfind('\n') + 1)
+ spacer = " "
+ if issubclass(arr.dtype.type, flexible):
+ spacer = '\n' + ' '*len(class_name + "(")
+ elif last_line_len + len(dtype_str) + 1 > max_line_width:
+ return arr_str + spacer + dtype_str
+def _array_repr_dispatcher(
+ arr, max_line_width=None, precision=None, suppress_small=None):
+ return (arr,)
+@array_function_dispatch(_array_repr_dispatcher, module='numpy')
+def array_repr(arr, max_line_width=None, precision=None, suppress_small=None):
+ Return the string representation of an array.
+ precision : int, optional
+ The string representation of an array.
+ array_str, array2string, set_printoptions
+ >>> np.array_repr(np.array([1,2]))
+ 'array([1, 2])'
+ >>> np.array_repr(np.ma.array([0.]))
+ 'MaskedArray([0.])'
+ >>> np.array_repr(np.array([], np.int32))
+ 'array([], dtype=int32)'
+ >>> x = np.array([1e-6, 4e-7, 2, 3])
+ >>> np.array_repr(x, precision=6, suppress_small=True)
+ 'array([0.000001, 0. , 2. , 3. ])'
+ return _array_repr_implementation(
+ arr, max_line_width, precision, suppress_small)
+def _guarded_repr_or_str(v):
+ if isinstance(v, bytes):
+ return repr(v)
+ return str(v)
+def _array_str_implementation(
+ a, max_line_width=None, precision=None, suppress_small=None,
+ """Internal version of array_str() that allows overriding array2string."""
+ a.shape == () and not a.dtype.names):
+ return str(a.item())
+ # the str of 0d arrays is a special case: It should appear like a scalar,
+ # so floats are not truncated by `precision`, and strings are not wrapped
+ # in quotes. So we return the str of the scalar value.
+ # obtain a scalar and call str on it, avoiding problems for subclasses
+ # for which indexing with () returns a 0d instead of a scalar by using
+ # ndarray's getindex. Also guard against recursive 0d object arrays.
+ return _guarded_repr_or_str(np.ndarray.__getitem__(a, ()))
+ return array2string(a, max_line_width, precision, suppress_small, ' ', "")
+def _array_str_dispatcher(
+ a, max_line_width=None, precision=None, suppress_small=None):
+@array_function_dispatch(_array_str_dispatcher, module='numpy')
+def array_str(a, max_line_width=None, precision=None, suppress_small=None):
+ Return a string representation of the data in an array.
+ The data in the array is returned as a single string. This function is
+ similar to `array_repr`, the difference being that `array_repr` also
+ returns information on the kind of array and its data type.
+ a : ndarray
+ array2string, array_repr, set_printoptions
+ >>> np.array_str(np.arange(3))
+ '[0 1 2]'
+ return _array_str_implementation(
+ a, max_line_width, precision, suppress_small)
+# needed if __array_function__ is disabled
+_array2string_impl = getattr(array2string, '__wrapped__', array2string)
+_default_array_str = functools.partial(_array_str_implementation,
+ array2string=_array2string_impl)
+_default_array_repr = functools.partial(_array_repr_implementation,
+def set_string_function(f, repr=True):
+ Set a Python function to be used when pretty printing arrays.
+ f : function or None
+ Function to be used to pretty print arrays. The function should expect
+ a single array argument and return a string of the representation of
+ the array. If None, the function is reset to the default NumPy function
+ to print arrays.
+ repr : bool, optional
+ If True (default), the function for pretty printing (``__repr__``)
+ is set, if False the function that returns the default string
+ representation (``__str__``) is set.
+ >>> def pprint(arr):
+ ... return 'HA! - What are you going to do now?'
+ >>> np.set_string_function(pprint)
+ >>> a = np.arange(10)
+ HA! - What are you going to do now?
+ >>> _ = a
+ >>> # [0 1 2 3 4 5 6 7 8 9]
+ We can reset the function to the default:
+ >>> np.set_string_function(None)
+ array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+ `repr` affects either pretty printing or normal string representation.
+ Note that ``__repr__`` is still affected by setting ``__str__``
+ because the width of each array element in the returned string becomes
+ equal to the length of the result of ``__str__()``.
+ >>> x = np.arange(4)
+ >>> np.set_string_function(lambda x:'random', repr=False)
+ >>> x.__str__()
+ 'random'
+ >>> x.__repr__()
+ 'array([0, 1, 2, 3])'
+ if f is None:
+ if repr:
+ return multiarray.set_string_function(_default_array_repr, 1)
+ return multiarray.set_string_function(_default_array_str, 0)
+ return multiarray.set_string_function(f, repr)
@@ -0,0 +1,13 @@
+"""Simple script to compute the api hash of the current API.
+The API has is defined by numpy_api_order and ufunc_api_order.
+from os.path import dirname
+from code_generators.genapi import fullapi_hash
+from code_generators.numpy_api import full_api
+ curdir = dirname(__file__)
+ print(fullapi_hash(full_api))
@@ -0,0 +1,2795 @@
+This module contains a set of functions for vectorized string
+operations and methods.
+.. note::
+ The `chararray` class exists for backwards compatibility with
+ Numarray, it is not recommended for new development. Starting from numpy
+ 1.4, if one needs arrays of strings, it is recommended to use arrays of
+ `dtype` `object_`, `string_` or `unicode_`, and use the free functions
+ in the `numpy.char` module for fast vectorized string operations.
+Some methods will only be available if the corresponding string method is
+available in your version of Python.
+The preferred alias for `defchararray` is `numpy.char`.
+from .numerictypes import (
+ string_, unicode_, integer, int_, object_, bool_, character)
+from .numeric import ndarray, compare_chararrays
+from .numeric import array as narray
+from numpy.core.multiarray import _vec_string
+from numpy.core import overrides
+from numpy.compat import asbytes
+ 'equal', 'not_equal', 'greater_equal', 'less_equal',
+ 'greater', 'less', 'str_len', 'add', 'multiply', 'mod', 'capitalize',
+ 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs',
+ 'find', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace',
+ 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition',
+ 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit',
+ 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase',
+ 'title', 'translate', 'upper', 'zfill', 'isnumeric', 'isdecimal',
+ 'array', 'asarray'
+_globalvar = 0
+array_function_dispatch = functools.partial(
+ overrides.array_function_dispatch, module='numpy.char')
+def _use_unicode(*args):
+ Helper function for determining the output type of some string
+ operations.
+ For an operation on two ndarrays, if at least one is unicode, the
+ result should be unicode.
+ for x in args:
+ if (isinstance(x, str) or
+ issubclass(numpy.asarray(x).dtype.type, unicode_)):
+ return unicode_
+ return string_
+def _to_string_or_unicode_array(result):
+ Helper function to cast a result back into a string or unicode array
+ if an object array must be used as an intermediary.
+ return numpy.asarray(result.tolist())
+def _clean_args(*args):
+ Helper function for delegating arguments to Python string
+ functions.
+ Many of the Python string operations that have optional arguments
+ do not use 'None' to indicate a default value. In these cases,
+ we need to remove all None arguments, and those following them.
+ newargs = []
+ for chk in args:
+ if chk is None:
+ newargs.append(chk)
+ return newargs
+def _get_num_chars(a):
+ Helper function that returns the number of characters per field in
+ a string or unicode array. This is to abstract out the fact that
+ for a unicode array this is itemsize / 4.
+ if issubclass(a.dtype.type, unicode_):
+ return a.itemsize // 4
+ return a.itemsize
+def _binary_op_dispatcher(x1, x2):
+ return (x1, x2)
+@array_function_dispatch(_binary_op_dispatcher)
+def equal(x1, x2):
+ Return (x1 == x2) element-wise.
+ Unlike `numpy.equal`, this comparison is performed by first
+ stripping whitespace characters from the end of the string. This
+ behavior is provided for backward-compatibility with numarray.
+ x1, x2 : array_like of str or unicode
+ Input arrays of the same shape.
+ Output array of bools.
+ not_equal, greater_equal, less_equal, greater, less
+ return compare_chararrays(x1, x2, '==', True)
+def not_equal(x1, x2):
+ Return (x1 != x2) element-wise.
+ Unlike `numpy.not_equal`, this comparison is performed by first
+ equal, greater_equal, less_equal, greater, less
+ return compare_chararrays(x1, x2, '!=', True)
+def greater_equal(x1, x2):
+ Return (x1 >= x2) element-wise.
+ Unlike `numpy.greater_equal`, this comparison is performed by
+ first stripping whitespace characters from the end of the string.
+ This behavior is provided for backward-compatibility with
+ numarray.
+ equal, not_equal, less_equal, greater, less
+ return compare_chararrays(x1, x2, '>=', True)
+def less_equal(x1, x2):
+ Return (x1 <= x2) element-wise.
+ Unlike `numpy.less_equal`, this comparison is performed by first
+ equal, not_equal, greater_equal, greater, less
+ return compare_chararrays(x1, x2, '<=', True)
+def greater(x1, x2):
+ Return (x1 > x2) element-wise.
+ Unlike `numpy.greater`, this comparison is performed by first
+ equal, not_equal, greater_equal, less_equal, less
+ return compare_chararrays(x1, x2, '>', True)
+def less(x1, x2):
+ Return (x1 < x2) element-wise.
+ equal, not_equal, greater_equal, less_equal, greater
+ return compare_chararrays(x1, x2, '<', True)
+def _unary_op_dispatcher(a):
+@array_function_dispatch(_unary_op_dispatcher)
+def str_len(a):
+ Return len(a) element-wise.
+ a : array_like of str or unicode
+ Output array of integers
+ builtins.len
+ # Note: __len__, etc. currently return ints, which are not C-integers.
+ # Generally intp would be expected for lengths, although int is sufficient
+ # due to the dtype itemsize limitation.
+ return _vec_string(a, int_, '__len__')
+def add(x1, x2):
+ Return element-wise string concatenation for two arrays of str or unicode.
+ Arrays `x1` and `x2` must have the same shape.
+ x1 : array_like of str or unicode
+ x2 : array_like of str or unicode
+ add : ndarray
+ Output array of `string_` or `unicode_`, depending on input types
+ of the same shape as `x1` and `x2`.
+ arr1 = numpy.asarray(x1)
+ arr2 = numpy.asarray(x2)
+ out_size = _get_num_chars(arr1) + _get_num_chars(arr2)
+ dtype = _use_unicode(arr1, arr2)
+ return _vec_string(arr1, (dtype, out_size), '__add__', (arr2,))
+def _multiply_dispatcher(a, i):
+@array_function_dispatch(_multiply_dispatcher)
+def multiply(a, i):
+ Return (a * i), that is string multiple concatenation,
+ element-wise.
+ Values in `i` of less than 0 are treated as 0 (which yields an
+ empty string).
+ i : array_like of ints
+ Output array of str or unicode, depending on input types
+ a_arr = numpy.asarray(a)
+ i_arr = numpy.asarray(i)
+ if not issubclass(i_arr.dtype.type, integer):
+ raise ValueError("Can only multiply by integers")
+ out_size = _get_num_chars(a_arr) * max(int(i_arr.max()), 0)
+ return _vec_string(
+ a_arr, (a_arr.dtype.type, out_size), '__mul__', (i_arr,))
+def _mod_dispatcher(a, values):
+ return (a, values)
+@array_function_dispatch(_mod_dispatcher)
+def mod(a, values):
+ Return (a % i), that is pre-Python 2.6 string formatting
+ (interpolation), element-wise for a pair of array_likes of str
+ or unicode.
+ values : array_like of values
+ These values will be element-wise interpolated into the string.
+ str.__mod__
+ return _to_string_or_unicode_array(
+ _vec_string(a, object_, '__mod__', (values,)))
+def capitalize(a):
+ Return a copy of `a` with only the first character of each element
+ capitalized.
+ Calls `str.capitalize` element-wise.
+ For 8-bit strings, this method is locale-dependent.
+ Input array of strings to capitalize.
+ Output array of str or unicode, depending on input
+ types
+ str.capitalize
+ >>> c = np.array(['a1b2','1b2a','b2a1','2a1b'],'S4'); c
+ array(['a1b2', '1b2a', 'b2a1', '2a1b'],
+ dtype='|S4')
+ >>> np.char.capitalize(c)
+ array(['A1b2', '1b2a', 'B2a1', '2a1b'],
+ return _vec_string(a_arr, a_arr.dtype, 'capitalize')
+def _center_dispatcher(a, width, fillchar=None):
+@array_function_dispatch(_center_dispatcher)
+def center(a, width, fillchar=' '):
+ Return a copy of `a` with its elements centered in a string of
+ length `width`.
+ Calls `str.center` element-wise.
+ width : int
+ The length of the resulting strings
+ fillchar : str or unicode, optional
+ The padding character to use (default is space).
+ str.center
+ width_arr = numpy.asarray(width)
+ size = int(numpy.max(width_arr.flat))
+ if numpy.issubdtype(a_arr.dtype, numpy.string_):
+ fillchar = asbytes(fillchar)
+ a_arr, (a_arr.dtype.type, size), 'center', (width_arr, fillchar))
+def _count_dispatcher(a, sub, start=None, end=None):
+@array_function_dispatch(_count_dispatcher)
+def count(a, sub, start=0, end=None):
+ Returns an array with the number of non-overlapping occurrences of
+ substring `sub` in the range [`start`, `end`].
+ Calls `str.count` element-wise.
+ sub : str or unicode
+ The substring to search for.
+ start, end : int, optional
+ Optional arguments `start` and `end` are interpreted as slice
+ notation to specify the range in which to count.
+ Output array of ints.
+ str.count
+ >>> c = np.array(['aAaAaA', ' aA ', 'abBABba'])
+ array(['aAaAaA', ' aA ', 'abBABba'], dtype='<U7')
+ >>> np.char.count(c, 'A')
+ array([3, 1, 1])
+ >>> np.char.count(c, 'aA')
+ array([3, 1, 0])
+ >>> np.char.count(c, 'A', start=1, end=4)
+ array([2, 1, 1])
+ >>> np.char.count(c, 'A', start=1, end=3)
+ array([1, 0, 0])
+ return _vec_string(a, int_, 'count', [sub, start] + _clean_args(end))
+def _code_dispatcher(a, encoding=None, errors=None):
+@array_function_dispatch(_code_dispatcher)
+def decode(a, encoding=None, errors=None):
+ Calls `str.decode` element-wise.
+ The set of available codecs comes from the Python standard library,
+ and may be extended at runtime. For more information, see the
+ :mod:`codecs` module.
+ encoding : str, optional
+ The name of an encoding
+ errors : str, optional
+ Specifies how to handle encoding errors
+ str.decode
+ The type of the result will depend on the encoding specified.
+ >>> np.char.encode(c, encoding='cp037')
+ array(['\\x81\\xc1\\x81\\xc1\\x81\\xc1', '@@\\x81\\xc1@@',
+ '\\x81\\x82\\xc2\\xc1\\xc2\\x82\\x81'],
+ dtype='|S7')
+ _vec_string(a, object_, 'decode', _clean_args(encoding, errors)))
+def encode(a, encoding=None, errors=None):
+ Calls `str.encode` element-wise.
+ and may be extended at runtime. For more information, see the codecs
+ str.encode
+ _vec_string(a, object_, 'encode', _clean_args(encoding, errors)))
+def _endswith_dispatcher(a, suffix, start=None, end=None):
+@array_function_dispatch(_endswith_dispatcher)
+def endswith(a, suffix, start=0, end=None):
+ Returns a boolean array which is `True` where the string element
+ in `a` ends with `suffix`, otherwise `False`.
+ Calls `str.endswith` element-wise.
+ suffix : str
+ With optional `start`, test beginning at that position. With
+ optional `end`, stop comparing at that position.
+ Outputs an array of bools.
+ str.endswith
+ >>> s = np.array(['foo', 'bar'])
+ >>> s[0] = 'foo'
+ >>> s[1] = 'bar'
+ >>> s
+ array(['foo', 'bar'], dtype='<U3')
+ >>> np.char.endswith(s, 'ar')
+ array([False, True])
+ >>> np.char.endswith(s, 'a', start=1, end=2)
+ a, bool_, 'endswith', [suffix, start] + _clean_args(end))
+def _expandtabs_dispatcher(a, tabsize=None):
+@array_function_dispatch(_expandtabs_dispatcher)
+def expandtabs(a, tabsize=8):
+ Return a copy of each string element where all tab characters are
+ replaced by one or more spaces.
+ Calls `str.expandtabs` element-wise.
+ replaced by one or more spaces, depending on the current column
+ and the given `tabsize`. The column number is reset to zero after
+ each newline occurring in the string. This doesn't understand other
+ non-printing characters or escape sequences.
+ Input array
+ tabsize : int, optional
+ Replace tabs with `tabsize` number of spaces. If not given defaults
+ to 8 spaces.
+ Output array of str or unicode, depending on input type
+ str.expandtabs
+ _vec_string(a, object_, 'expandtabs', (tabsize,)))
+def find(a, sub, start=0, end=None):
+ For each element, return the lowest index in the string where
+ substring `sub` is found.
+ Calls `str.find` element-wise.
+ substring `sub` is found, such that `sub` is contained in the
+ range [`start`, `end`].
+ Optional arguments `start` and `end` are interpreted as in
+ slice notation.
+ out : ndarray or int
+ Output array of ints. Returns -1 if `sub` is not found.
+ str.find
+ a, int_, 'find', [sub, start] + _clean_args(end))
+def index(a, sub, start=0, end=None):
+ Like `find`, but raises `ValueError` when the substring is not found.
+ Calls `str.index` element-wise.
+ find, str.find
+ a, int_, 'index', [sub, start] + _clean_args(end))
+def isalnum(a):
+ Returns true for each element if all characters in the string are
+ alphanumeric and there is at least one character, false otherwise.
+ Calls `str.isalnum` element-wise.
+ str.isalnum
+ return _vec_string(a, bool_, 'isalnum')
+def isalpha(a):
+ alphabetic and there is at least one character, false otherwise.
+ Calls `str.isalpha` element-wise.
+ Output array of bools
+ str.isalpha
+ return _vec_string(a, bool_, 'isalpha')
+def isdigit(a):
+ digits and there is at least one character, false otherwise.
+ Calls `str.isdigit` element-wise.
+ str.isdigit
+ return _vec_string(a, bool_, 'isdigit')
+def islower(a):
+ Returns true for each element if all cased characters in the
+ string are lowercase and there is at least one cased character,
+ false otherwise.
+ Calls `str.islower` element-wise.
+ str.islower
+ return _vec_string(a, bool_, 'islower')
+def isspace(a):
+ Returns true for each element if there are only whitespace
+ characters in the string and there is at least one character,
+ Calls `str.isspace` element-wise.
+ str.isspace
+ return _vec_string(a, bool_, 'isspace')
+def istitle(a):
+ Returns true for each element if the element is a titlecased
+ string and there is at least one character, false otherwise.
+ Call `str.istitle` element-wise.
+ str.istitle
+ return _vec_string(a, bool_, 'istitle')
+def isupper(a):
+ string are uppercase and there is at least one character, false
+ otherwise.
+ Call `str.isupper` element-wise.
+ str.isupper
+ return _vec_string(a, bool_, 'isupper')
+def _join_dispatcher(sep, seq):
+ return (sep, seq)
+@array_function_dispatch(_join_dispatcher)
+def join(sep, seq):
+ Return a string which is the concatenation of the strings in the
+ sequence `seq`.
+ Calls `str.join` element-wise.
+ sep : array_like of str or unicode
+ seq : array_like of str or unicode
+ str.join
+ _vec_string(sep, object_, 'join', (seq,)))
+def _just_dispatcher(a, width, fillchar=None):
+@array_function_dispatch(_just_dispatcher)
+def ljust(a, width, fillchar=' '):
+ Return an array with the elements of `a` left-justified in a
+ string of length `width`.
+ Calls `str.ljust` element-wise.
+ The character to use for padding
+ str.ljust
+ a_arr, (a_arr.dtype.type, size), 'ljust', (width_arr, fillchar))
+def lower(a):
+ Return an array with the elements converted to lowercase.
+ Call `str.lower` element-wise.
+ a : array_like, {str, unicode}
+ out : ndarray, {str, unicode}
+ str.lower
+ >>> c = np.array(['A1B C', '1BCA', 'BCA1']); c
+ array(['A1B C', '1BCA', 'BCA1'], dtype='<U5')
+ >>> np.char.lower(c)
+ array(['a1b c', '1bca', 'bca1'], dtype='<U5')
+ return _vec_string(a_arr, a_arr.dtype, 'lower')
+def _strip_dispatcher(a, chars=None):
+@array_function_dispatch(_strip_dispatcher)
+def lstrip(a, chars=None):
+ For each element in `a`, return a copy with the leading characters
+ removed.
+ Calls `str.lstrip` element-wise.
+ a : array-like, {str, unicode}
+ chars : {str, unicode}, optional
+ The `chars` argument is a string specifying the set of
+ characters to be removed. If omitted or None, the `chars`
+ argument defaults to removing whitespace. The `chars` argument
+ is not a prefix; rather, all combinations of its values are
+ stripped.
+ str.lstrip
+ The 'a' variable is unstripped from c[1] because whitespace leading.
+ >>> np.char.lstrip(c, 'a')
+ array(['AaAaA', ' aA ', 'bBABba'], dtype='<U7')
+ >>> np.char.lstrip(c, 'A') # leaves c unchanged
+ >>> (np.char.lstrip(c, ' ') == np.char.lstrip(c, '')).all()
+ ... # XXX: is this a regression? This used to return True
+ ... # np.char.lstrip(c,'') does not modify c at all.
+ >>> (np.char.lstrip(c, ' ') == np.char.lstrip(c, None)).all()
+ return _vec_string(a_arr, a_arr.dtype, 'lstrip', (chars,))
+def _partition_dispatcher(a, sep):
+@array_function_dispatch(_partition_dispatcher)
+def partition(a, sep):
+ Partition each element in `a` around `sep`.
+ Calls `str.partition` element-wise.
+ For each element in `a`, split the element as the first
+ occurrence of `sep`, and return 3 strings containing the part
+ before the separator, the separator itself, and the part after
+ the separator. If the separator is not found, return 3 strings
+ containing the string itself, followed by two empty strings.
+ sep : {str, unicode}
+ Separator to split each string element in `a`.
+ Output array of str or unicode, depending on input type.
+ The output array will have an extra dimension with 3
+ elements per input element.
+ str.partition
+ _vec_string(a, object_, 'partition', (sep,)))
+def _replace_dispatcher(a, old, new, count=None):
+@array_function_dispatch(_replace_dispatcher)
+def replace(a, old, new, count=None):
+ For each element in `a`, return a copy of the string with all
+ occurrences of substring `old` replaced by `new`.
+ Calls `str.replace` element-wise.
+ a : array-like of str or unicode
+ old, new : str or unicode
+ If the optional argument `count` is given, only the first
+ `count` occurrences are replaced.
+ str.replace
+ _vec_string(
+ a, object_, 'replace', [old, new] + _clean_args(count)))
+def rfind(a, sub, start=0, end=None):
+ For each element in `a`, return the highest index in the string
+ where substring `sub` is found, such that `sub` is contained
+ within [`start`, `end`].
+ Calls `str.rfind` element-wise.
+ Output array of ints. Return -1 on failure.
+ str.rfind
+ a, int_, 'rfind', [sub, start] + _clean_args(end))
+def rindex(a, sub, start=0, end=None):
+ Like `rfind`, but raises `ValueError` when the substring `sub` is
+ not found.
+ Calls `str.rindex` element-wise.
+ rfind, str.rindex
+ a, int_, 'rindex', [sub, start] + _clean_args(end))
+def rjust(a, width, fillchar=' '):
+ Return an array with the elements of `a` right-justified in a
+ Calls `str.rjust` element-wise.
+ str.rjust
+ a_arr, (a_arr.dtype.type, size), 'rjust', (width_arr, fillchar))
+def rpartition(a, sep):
+ Partition (split) each element around the right-most separator.
+ Calls `str.rpartition` element-wise.
+ For each element in `a`, split the element as the last
+ sep : str or unicode
+ Right-most separator to split each element in array.
+ Output array of string or unicode, depending on input
+ type. The output array will have an extra dimension with
+ 3 elements per input element.
+ str.rpartition
+ _vec_string(a, object_, 'rpartition', (sep,)))
+def _split_dispatcher(a, sep=None, maxsplit=None):
+@array_function_dispatch(_split_dispatcher)
+def rsplit(a, sep=None, maxsplit=None):
+ For each element in `a`, return a list of the words in the
+ string, using `sep` as the delimiter string.
+ Calls `str.rsplit` element-wise.
+ Except for splitting from the right, `rsplit`
+ behaves like `split`.
+ sep : str or unicode, optional
+ If `sep` is not specified or None, any whitespace string
+ is a separator.
+ maxsplit : int, optional
+ If `maxsplit` is given, at most `maxsplit` splits are done,
+ the rightmost ones.
+ Array of list objects
+ str.rsplit, split
+ # This will return an array of lists of different sizes, so we
+ # leave it as an object array
+ a, object_, 'rsplit', [sep] + _clean_args(maxsplit))
+def rstrip(a, chars=None):
+ For each element in `a`, return a copy with the trailing
+ characters removed.
+ Calls `str.rstrip` element-wise.
+ chars : str or unicode, optional
+ is not a suffix; rather, all combinations of its values are
+ str.rstrip
+ >>> c = np.array(['aAaAaA', 'abBABba'], dtype='S7'); c
+ array(['aAaAaA', 'abBABba'],
+ >>> np.char.rstrip(c, b'a')
+ array(['aAaAaA', 'abBABb'],
+ >>> np.char.rstrip(c, b'A')
+ array(['aAaAa', 'abBABba'],
+ return _vec_string(a_arr, a_arr.dtype, 'rstrip', (chars,))
+def split(a, sep=None, maxsplit=None):
+ Calls `str.split` element-wise.
+ If `sep` is not specified or None, any whitespace string is a
+ separator.
+ If `maxsplit` is given, at most `maxsplit` splits are done.
+ str.split, rsplit
+ a, object_, 'split', [sep] + _clean_args(maxsplit))
+def _splitlines_dispatcher(a, keepends=None):
+@array_function_dispatch(_splitlines_dispatcher)
+def splitlines(a, keepends=None):
+ For each element in `a`, return a list of the lines in the
+ element, breaking at line boundaries.
+ Calls `str.splitlines` element-wise.
+ keepends : bool, optional
+ Line breaks are not included in the resulting list unless
+ keepends is given and true.
+ str.splitlines
+ a, object_, 'splitlines', _clean_args(keepends))
+def _startswith_dispatcher(a, prefix, start=None, end=None):
+@array_function_dispatch(_startswith_dispatcher)
+def startswith(a, prefix, start=0, end=None):
+ in `a` starts with `prefix`, otherwise `False`.
+ Calls `str.startswith` element-wise.
+ prefix : str
+ Array of booleans
+ str.startswith
+ a, bool_, 'startswith', [prefix, start] + _clean_args(end))
+def strip(a, chars=None):
+ For each element in `a`, return a copy with the leading and
+ trailing characters removed.
+ Calls `str.strip` element-wise.
+ is not a prefix or suffix; rather, all combinations of its
+ values are stripped.
+ str.strip
+ >>> np.char.strip(c)
+ array(['aAaAaA', 'aA', 'abBABba'], dtype='<U7')
+ >>> np.char.strip(c, 'a') # 'a' unstripped from c[1] because whitespace leads
+ array(['AaAaA', ' aA ', 'bBABb'], dtype='<U7')
+ >>> np.char.strip(c, 'A') # 'A' unstripped from c[1] because (unprinted) ws trails
+ array(['aAaAa', ' aA ', 'abBABba'], dtype='<U7')
+ return _vec_string(a_arr, a_arr.dtype, 'strip', _clean_args(chars))
+def swapcase(a):
+ Return element-wise a copy of the string with
+ uppercase characters converted to lowercase and vice versa.
+ Calls `str.swapcase` element-wise.
+ str.swapcase
+ >>> c=np.array(['a1B c','1b Ca','b Ca1','cA1b'],'S5'); c
+ array(['a1B c', '1b Ca', 'b Ca1', 'cA1b'],
+ dtype='|S5')
+ >>> np.char.swapcase(c)
+ array(['A1b C', '1B cA', 'B cA1', 'Ca1B'],
+ return _vec_string(a_arr, a_arr.dtype, 'swapcase')
+def title(a):
+ Return element-wise title cased version of string or unicode.
+ Title case words start with uppercase characters, all remaining cased
+ characters are lowercase.
+ Calls `str.title` element-wise.
+ str.title
+ >>> c=np.array(['a1b c','1b ca','b ca1','ca1b'],'S5'); c
+ array(['a1b c', '1b ca', 'b ca1', 'ca1b'],
+ >>> np.char.title(c)
+ array(['A1B C', '1B Ca', 'B Ca1', 'Ca1B'],
+ return _vec_string(a_arr, a_arr.dtype, 'title')
+def _translate_dispatcher(a, table, deletechars=None):
+@array_function_dispatch(_translate_dispatcher)
+def translate(a, table, deletechars=None):
+ For each element in `a`, return a copy of the string where all
+ characters occurring in the optional argument `deletechars` are
+ removed, and the remaining characters have been mapped through the
+ given translation table.
+ Calls `str.translate` element-wise.
+ table : str of length 256
+ deletechars : str
+ str.translate
+ if issubclass(a_arr.dtype.type, unicode_):
+ a_arr, a_arr.dtype, 'translate', (table,))
+ a_arr, a_arr.dtype, 'translate', [table] + _clean_args(deletechars))
+def upper(a):
+ Return an array with the elements converted to uppercase.
+ Calls `str.upper` element-wise.
+ str.upper
+ >>> c = np.array(['a1b c', '1bca', 'bca1']); c
+ >>> np.char.upper(c)
+ return _vec_string(a_arr, a_arr.dtype, 'upper')
+def _zfill_dispatcher(a, width):
+@array_function_dispatch(_zfill_dispatcher)
+def zfill(a, width):
+ Return the numeric string left-filled with zeros
+ Calls `str.zfill` element-wise.
+ Width of string to left-fill elements in `a`.
+ str.zfill
+ a_arr, (a_arr.dtype.type, size), 'zfill', (width_arr,))
+def isnumeric(a):
+ For each element, return True if there are only numeric
+ characters in the element.
+ Calls `unicode.isnumeric` element-wise.
+ Numeric characters include digit characters, and all characters
+ that have the Unicode numeric value property, e.g. ``U+2155,
+ VULGAR FRACTION ONE FIFTH``.
+ a : array_like, unicode
+ out : ndarray, bool
+ Array of booleans of same shape as `a`.
+ unicode.isnumeric
+ if _use_unicode(a) != unicode_:
+ raise TypeError("isnumeric is only available for Unicode strings and arrays")
+ return _vec_string(a, bool_, 'isnumeric')
+def isdecimal(a):
+ For each element, return True if there are only decimal
+ Calls `unicode.isdecimal` element-wise.
+ Decimal characters include digit characters, and all characters
+ that can be used to form decimal-radix numbers,
+ e.g. ``U+0660, ARABIC-INDIC DIGIT ZERO``.
+ Array of booleans identical in shape to `a`.
+ unicode.isdecimal
+ return _vec_string(a, bool_, 'isdecimal')
+class chararray(ndarray):
+ chararray(shape, itemsize=1, unicode=False, buffer=None, offset=0,
+ Provides a convenient view on arrays of string and unicode values.
+ Versus a regular NumPy array of type `str` or `unicode`, this
+ class adds the following functionality:
+ 1) values automatically have whitespace removed from the end
+ when indexed
+ 2) comparison operators automatically remove whitespace from the
+ end when comparing values
+ 3) vectorized string operations are provided as methods
+ (e.g. `.endswith`) and infix operators (e.g. ``"+", "*", "%"``)
+ chararrays should be created using `numpy.char.array` or
+ `numpy.char.asarray`, rather than this constructor directly.
+ This constructor creates the array, using `buffer` (with `offset`
+ and `strides`) if it is not ``None``. If `buffer` is ``None``, then
+ constructs a new array with `strides` in "C order", unless both
+ ``len(shape) >= 2`` and ``order='F'``, in which case `strides`
+ is in "Fortran order".
+ Methods
+ astype
+ argsort
+ copy
+ count
+ decode
+ dump
+ dumps
+ encode
+ endswith
+ expandtabs
+ fill
+ find
+ flatten
+ isalnum
+ isalpha
+ isdecimal
+ isdigit
+ islower
+ isnumeric
+ isspace
+ istitle
+ isupper
+ item
+ join
+ ljust
+ lower
+ lstrip
+ nonzero
+ put
+ ravel
+ repeat
+ replace
+ reshape
+ resize
+ rfind
+ rindex
+ rjust
+ rsplit
+ rstrip
+ searchsorted
+ setfield
+ setflags
+ sort
+ split
+ splitlines
+ squeeze
+ startswith
+ strip
+ swapaxes
+ swapcase
+ take
+ title
+ tofile
+ tolist
+ tostring
+ translate
+ upper
+ view
+ zfill
+ itemsize : int, optional
+ Length of each array element, in number of characters. Default is 1.
+ unicode : bool, optional
+ Are the array elements of type unicode (True) or string (False).
+ Default is False.
+ buffer : object exposing the buffer interface or str, optional
+ Memory address of the start of the array data. Default is None,
+ in which case a new array is created.
+ Fixed stride displacement from the beginning of an axis?
+ Default is 0. Needs to be >=0.
+ strides : array_like of ints, optional
+ Strides for the array (see `ndarray.strides` for full description).
+ Default is None.
+ The order in which the array data is stored in memory: 'C' ->
+ "row major" order (the default), 'F' -> "column major"
+ (Fortran) order.
+ >>> charar = np.chararray((3, 3))
+ >>> charar[:] = 'a'
+ >>> charar
+ chararray([[b'a', b'a', b'a'],
+ [b'a', b'a', b'a'],
+ [b'a', b'a', b'a']], dtype='|S1')
+ >>> charar = np.chararray(charar.shape, itemsize=5)
+ >>> charar[:] = 'abc'
+ chararray([[b'abc', b'abc', b'abc'],
+ [b'abc', b'abc', b'abc'],
+ [b'abc', b'abc', b'abc']], dtype='|S5')
+ def __new__(subtype, shape, itemsize=1, unicode=False, buffer=None,
+ offset=0, strides=None, order='C'):
+ global _globalvar
+ if unicode:
+ dtype = unicode_
+ dtype = string_
+ # force itemsize to be a Python int, since using NumPy integer
+ # types results in itemsize.itemsize being used as the size of
+ # strings in the new array.
+ itemsize = int(itemsize)
+ if isinstance(buffer, str):
+ # unicode objects do not have the buffer interface
+ filler = buffer
+ buffer = None
+ filler = None
+ _globalvar = 1
+ if buffer is None:
+ self = ndarray.__new__(subtype, shape, (dtype, itemsize),
+ order=order)
+ buffer=buffer,
+ offset=offset, strides=strides,
+ if filler is not None:
+ self[...] = filler
+ _globalvar = 0
+ def __array_finalize__(self, obj):
+ # The b is a special case because it is used for reconstructing.
+ if not _globalvar and self.dtype.char not in 'SUbc':
+ raise ValueError("Can only create a chararray from string data.")
+ def __getitem__(self, obj):
+ val = ndarray.__getitem__(self, obj)
+ if isinstance(val, character):
+ temp = val.rstrip()
+ if len(temp) == 0:
+ val = ''
+ val = temp
+ # IMPLEMENTATION NOTE: Most of the methods of this class are
+ # direct delegations to the free functions in this module.
+ # However, those that return an array of strings should instead
+ # return a chararray, so some extra wrapping is required.
+ Return (self == other) element-wise.
+ equal
+ return equal(self, other)
+ Return (self != other) element-wise.
+ not_equal
+ return not_equal(self, other)
+ def __ge__(self, other):
+ Return (self >= other) element-wise.
+ greater_equal
+ return greater_equal(self, other)
+ def __le__(self, other):
+ Return (self <= other) element-wise.
+ less_equal
+ return less_equal(self, other)
+ def __gt__(self, other):
+ Return (self > other) element-wise.
+ greater
+ return greater(self, other)
+ def __lt__(self, other):
+ Return (self < other) element-wise.
+ less
+ return less(self, other)
+ def __add__(self, other):
+ Return (self + other), that is string concatenation,
+ element-wise for a pair of array_likes of str or unicode.
+ add
+ return asarray(add(self, other))
+ def __radd__(self, other):
+ Return (other + self), that is string concatenation,
+ element-wise for a pair of array_likes of `string_` or `unicode_`.
+ return asarray(add(numpy.asarray(other), self))
+ def __mul__(self, i):
+ Return (self * i), that is string multiple concatenation,
+ multiply
+ return asarray(multiply(self, i))
+ def __rmul__(self, i):
+ def __mod__(self, i):
+ Return (self % i), that is pre-Python 2.6 string formatting
+ (interpolation), element-wise for a pair of array_likes of `string_`
+ or `unicode_`.
+ mod
+ return asarray(mod(self, i))
+ def __rmod__(self, other):
+ return NotImplemented
+ def argsort(self, axis=-1, kind=None, order=None):
+ Return the indices that sort the array lexicographically.
+ For full documentation see `numpy.argsort`, for which this method is
+ in fact merely a "thin wrapper."
+ >>> c = np.array(['a1b c', '1b ca', 'b ca1', 'Ca1b'], 'S5')
+ >>> c = c.view(np.chararray); c
+ chararray(['a1b c', '1b ca', 'b ca1', 'Ca1b'],
+ >>> c[c.argsort()]
+ chararray(['1b ca', 'Ca1b', 'a1b c', 'b ca1'],
+ return self.__array__().argsort(axis, kind, order)
+ argsort.__doc__ = ndarray.argsort.__doc__
+ def capitalize(self):
+ Return a copy of `self` with only the first character of each element
+ char.capitalize
+ return asarray(capitalize(self))
+ def center(self, width, fillchar=' '):
+ Return a copy of `self` with its elements centered in a
+ center
+ return asarray(center(self, width, fillchar))
+ def count(self, sub, start=0, end=None):
+ char.count
+ return count(self, sub, start, end)
+ def decode(self, encoding=None, errors=None):
+ char.decode
+ return decode(self, encoding, errors)
+ def encode(self, encoding=None, errors=None):
+ char.encode
+ return encode(self, encoding, errors)
+ def endswith(self, suffix, start=0, end=None):
+ in `self` ends with `suffix`, otherwise `False`.
+ char.endswith
+ return endswith(self, suffix, start, end)
+ def expandtabs(self, tabsize=8):
+ char.expandtabs
+ return asarray(expandtabs(self, tabsize))
+ def find(self, sub, start=0, end=None):
+ char.find
+ return find(self, sub, start, end)
+ def index(self, sub, start=0, end=None):
+ char.index
+ return index(self, sub, start, end)
+ def isalnum(self):
+ Returns true for each element if all characters in the string
+ are alphanumeric and there is at least one character, false
+ char.isalnum
+ return isalnum(self)
+ def isalpha(self):
+ are alphabetic and there is at least one character, false
+ char.isalpha
+ return isalpha(self)
+ def isdigit(self):
+ char.isdigit
+ return isdigit(self)
+ def islower(self):
+ char.islower
+ return islower(self)
+ def isspace(self):
+ char.isspace
+ return isspace(self)
+ def istitle(self):
+ char.istitle
+ return istitle(self)
+ def isupper(self):
+ char.isupper
+ return isupper(self)
+ def join(self, seq):
+ char.join
+ return join(self, seq)
+ def ljust(self, width, fillchar=' '):
+ Return an array with the elements of `self` left-justified in a
+ char.ljust
+ return asarray(ljust(self, width, fillchar))
+ def lower(self):
+ Return an array with the elements of `self` converted to
+ lowercase.
+ char.lower
+ return asarray(lower(self))
+ def lstrip(self, chars=None):
+ For each element in `self`, return a copy with the leading characters
+ char.lstrip
+ return asarray(lstrip(self, chars))
+ def partition(self, sep):
+ Partition each element in `self` around `sep`.
+ partition
+ return asarray(partition(self, sep))
+ def replace(self, old, new, count=None):
+ For each element in `self`, return a copy of the string with all
+ char.replace
+ return asarray(replace(self, old, new, count))
+ def rfind(self, sub, start=0, end=None):
+ For each element in `self`, return the highest index in the string
+ char.rfind
+ return rfind(self, sub, start, end)
+ def rindex(self, sub, start=0, end=None):
+ char.rindex
+ return rindex(self, sub, start, end)
+ def rjust(self, width, fillchar=' '):
+ Return an array with the elements of `self`
+ right-justified in a string of length `width`.
+ char.rjust
+ return asarray(rjust(self, width, fillchar))
+ def rpartition(self, sep):
+ rpartition
+ return asarray(rpartition(self, sep))
+ def rsplit(self, sep=None, maxsplit=None):
+ For each element in `self`, return a list of the words in
+ the string, using `sep` as the delimiter string.
+ char.rsplit
+ return rsplit(self, sep, maxsplit)
+ def rstrip(self, chars=None):
+ For each element in `self`, return a copy with the trailing
+ char.rstrip
+ return asarray(rstrip(self, chars))
+ def split(self, sep=None, maxsplit=None):
+ For each element in `self`, return a list of the words in the
+ char.split
+ return split(self, sep, maxsplit)
+ def splitlines(self, keepends=None):
+ For each element in `self`, return a list of the lines in the
+ char.splitlines
+ return splitlines(self, keepends)
+ def startswith(self, prefix, start=0, end=None):
+ in `self` starts with `prefix`, otherwise `False`.
+ char.startswith
+ return startswith(self, prefix, start, end)
+ def strip(self, chars=None):
+ For each element in `self`, return a copy with the leading and
+ char.strip
+ return asarray(strip(self, chars))
+ def swapcase(self):
+ For each element in `self`, return a copy of the string with
+ char.swapcase
+ return asarray(swapcase(self))
+ def title(self):
+ For each element in `self`, return a titlecased version of the
+ string: words start with uppercase characters, all remaining cased
+ char.title
+ return asarray(title(self))
+ def translate(self, table, deletechars=None):
+ For each element in `self`, return a copy of the string where
+ all characters occurring in the optional argument
+ `deletechars` are removed, and the remaining characters have
+ been mapped through the given translation table.
+ char.translate
+ return asarray(translate(self, table, deletechars))
+ def upper(self):
+ uppercase.
+ char.upper
+ return asarray(upper(self))
+ def zfill(self, width):
+ Return the numeric string left-filled with zeros in a string of
+ char.zfill
+ return asarray(zfill(self, width))
+ def isnumeric(self):
+ For each element in `self`, return True if there are only
+ numeric characters in the element.
+ char.isnumeric
+ return isnumeric(self)
+ def isdecimal(self):
+ decimal characters in the element.
+ char.isdecimal
+ return isdecimal(self)
+def array(obj, itemsize=None, copy=True, unicode=None, order=None):
+ Create a `chararray`.
+ This class is provided for numarray backward-compatibility.
+ New code (not concerned with numarray compatibility) should use
+ arrays of type `string_` or `unicode_` and use the free functions
+ in :mod:`numpy.char <numpy.core.defchararray>` for fast
+ vectorized string operations instead.
+ (e.g. `str.endswith`) and infix operators (e.g. ``+, *, %``)
+ obj : array of str or unicode-like
+ `itemsize` is the number of characters per scalar in the
+ resulting array. If `itemsize` is None, and `obj` is an
+ object array or a Python list, the `itemsize` will be
+ automatically determined. If `itemsize` is provided and `obj`
+ is of type str or unicode, then the `obj` string will be
+ chunked into `itemsize` pieces.
+ If true (default), then the object is copied. Otherwise, a copy
+ will only be made if __array__ returns a copy, if obj is a
+ nested sequence, or if a copy is needed to satisfy any of the other
+ requirements (`itemsize`, unicode, `order`, etc.).
+ When true, the resulting `chararray` can contain Unicode
+ characters, when false only 8-bit characters. If unicode is
+ None and `obj` is one of the following:
+ - a `chararray`,
+ - an ndarray of type `str` or `unicode`
+ - a Python str or unicode object,
+ then the unicode setting of the output array will be
+ automatically determined.
+ Specify the order of the array. If order is 'C' (default), then the
+ array will be in C-contiguous order (last-index varies the
+ fastest). If order is 'F', then the returned array
+ will be in Fortran-contiguous order (first-index varies the
+ fastest). If order is 'A', then the returned array may
+ be in any order (either C-, Fortran-contiguous, or even
+ discontiguous).
+ if isinstance(obj, (bytes, str)):
+ if unicode is None:
+ if isinstance(obj, str):
+ unicode = True
+ unicode = False
+ if itemsize is None:
+ itemsize = len(obj)
+ shape = len(obj) // itemsize
+ return chararray(shape, itemsize=itemsize, unicode=unicode,
+ buffer=obj, order=order)
+ if isinstance(obj, (list, tuple)):
+ obj = numpy.asarray(obj)
+ if isinstance(obj, ndarray) and issubclass(obj.dtype.type, character):
+ # If we just have a vanilla chararray, create a chararray
+ # view around it.
+ if not isinstance(obj, chararray):
+ obj = obj.view(chararray)
+ itemsize = obj.itemsize
+ # itemsize is in 8-bit chars, so for Unicode, we need
+ # to divide by the size of a single Unicode character,
+ # which for NumPy is always 4
+ if issubclass(obj.dtype.type, unicode_):
+ itemsize //= 4
+ if order is not None:
+ obj = numpy.asarray(obj, order=order)
+ if (copy or
+ (itemsize != obj.itemsize) or
+ (not unicode and isinstance(obj, unicode_)) or
+ (unicode and isinstance(obj, string_))):
+ obj = obj.astype((dtype, int(itemsize)))
+ return obj
+ if isinstance(obj, ndarray) and issubclass(obj.dtype.type, object):
+ # Since no itemsize was specified, convert the input array to
+ # a list so the ndarray constructor will automatically
+ # determine the itemsize for us.
+ obj = obj.tolist()
+ # Fall through to the default case
+ val = narray(obj, dtype=dtype, order=order, subok=True)
+ val = narray(obj, dtype=(dtype, itemsize), order=order, subok=True)
+ return val.view(chararray)
+def asarray(obj, itemsize=None, unicode=None, order=None):
+ Convert the input to a `chararray`, copying the data only if
+ necessary.
+ (e.g. `str.endswith`) and infix operators (e.g. ``+``, ``*``,``%``)
+ - an ndarray of type `str` or 'unicode`
+ fastest).
+ return array(obj, itemsize, copy=False,
+ unicode=unicode, order=order)
@@ -0,0 +1,1433 @@
+Implementation of optimized einsum.
+import itertools
+import operator
+from numpy.core.multiarray import c_einsum
+from numpy.core.numeric import asanyarray, tensordot
+from numpy.core.overrides import array_function_dispatch
+__all__ = ['einsum', 'einsum_path']
+einsum_symbols = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
+einsum_symbols_set = set(einsum_symbols)
+def _flop_count(idx_contraction, inner, num_terms, size_dictionary):
+ Computes the number of FLOPS in the contraction.
+ idx_contraction : iterable
+ The indices involved in the contraction
+ inner : bool
+ Does this contraction require an inner product?
+ num_terms : int
+ The number of terms in a contraction
+ size_dictionary : dict
+ The size of each of the indices in idx_contraction
+ flop_count : int
+ The total number of FLOPS required for the contraction.
+ >>> _flop_count('abc', False, 1, {'a': 2, 'b':3, 'c':5})
+ >>> _flop_count('abc', True, 2, {'a': 2, 'b':3, 'c':5})
+ overall_size = _compute_size_by_dict(idx_contraction, size_dictionary)
+ op_factor = max(1, num_terms - 1)
+ if inner:
+ op_factor += 1
+ return overall_size * op_factor
+def _compute_size_by_dict(indices, idx_dict):
+ Computes the product of the elements in indices based on the dictionary
+ idx_dict.
+ indices : iterable
+ Indices to base the product on.
+ idx_dict : dictionary
+ Dictionary of index sizes
+ ret : int
+ The resulting product.
+ >>> _compute_size_by_dict('abbc', {'a': 2, 'b':3, 'c':5})
+ 90
+ ret = 1
+ for i in indices:
+ ret *= idx_dict[i]
+def _find_contraction(positions, input_sets, output_set):
+ Finds the contraction for a given set of input and output sets.
+ positions : iterable
+ Integer positions of terms used in the contraction.
+ input_sets : list
+ List of sets that represent the lhs side of the einsum subscript
+ output_set : set
+ Set that represents the rhs side of the overall einsum subscript
+ new_result : set
+ The indices of the resulting contraction
+ remaining : list
+ List of sets that have not been contracted, the new set is appended to
+ the end of this list
+ idx_removed : set
+ Indices removed from the entire contraction
+ idx_contraction : set
+ The indices used in the current contraction
+ # A simple dot product test case
+ >>> pos = (0, 1)
+ >>> isets = [set('ab'), set('bc')]
+ >>> oset = set('ac')
+ >>> _find_contraction(pos, isets, oset)
+ ({'a', 'c'}, [{'a', 'c'}], {'b'}, {'a', 'b', 'c'})
+ # A more complex case with additional terms in the contraction
+ >>> pos = (0, 2)
+ >>> isets = [set('abd'), set('ac'), set('bdc')]
+ ({'a', 'c'}, [{'a', 'c'}, {'a', 'c'}], {'b', 'd'}, {'a', 'b', 'c', 'd'})
+ idx_contract = set()
+ idx_remain = output_set.copy()
+ remaining = []
+ for ind, value in enumerate(input_sets):
+ if ind in positions:
+ idx_contract |= value
+ remaining.append(value)
+ idx_remain |= value
+ new_result = idx_remain & idx_contract
+ idx_removed = (idx_contract - new_result)
+ remaining.append(new_result)
+ return (new_result, remaining, idx_removed, idx_contract)
+def _optimal_path(input_sets, output_set, idx_dict, memory_limit):
+ Computes all possible pair contractions, sieves the results based
+ on ``memory_limit`` and returns the lowest cost path. This algorithm
+ scales factorial with respect to the elements in the list ``input_sets``.
+ memory_limit : int
+ The maximum number of elements in a temporary array
+ path : list
+ The optimal contraction order within the memory limit constraint.
+ >>> oset = set()
+ >>> idx_sizes = {'a': 1, 'b':2, 'c':3, 'd':4}
+ >>> _optimal_path(isets, oset, idx_sizes, 5000)
+ [(0, 2), (0, 1)]
+ full_results = [(0, [], input_sets)]
+ for iteration in range(len(input_sets) - 1):
+ iter_results = []
+ # Compute all unique pairs
+ for curr in full_results:
+ cost, positions, remaining = curr
+ for con in itertools.combinations(range(len(input_sets) - iteration), 2):
+ # Find the contraction
+ cont = _find_contraction(con, remaining, output_set)
+ new_result, new_input_sets, idx_removed, idx_contract = cont
+ # Sieve the results based on memory_limit
+ new_size = _compute_size_by_dict(new_result, idx_dict)
+ if new_size > memory_limit:
+ # Build (total_cost, positions, indices_remaining)
+ total_cost = cost + _flop_count(idx_contract, idx_removed, len(con), idx_dict)
+ new_pos = positions + [con]
+ iter_results.append((total_cost, new_pos, new_input_sets))
+ # Update combinatorial list, if we did not find anything return best
+ # path + remaining contractions
+ if iter_results:
+ full_results = iter_results
+ path = min(full_results, key=lambda x: x[0])[1]
+ path += [tuple(range(len(input_sets) - iteration))]
+ return path
+ # If we have not found anything return single einsum contraction
+ if len(full_results) == 0:
+ return [tuple(range(len(input_sets)))]
+def _parse_possible_contraction(positions, input_sets, output_set, idx_dict, memory_limit, path_cost, naive_cost):
+ """Compute the cost (removed size + flops) and resultant indices for
+ performing the contraction specified by ``positions``.
+ positions : tuple of int
+ The locations of the proposed tensors to contract.
+ input_sets : list of sets
+ The indices found on each tensors.
+ The output indices of the expression.
+ idx_dict : dict
+ Mapping of each index to its size.
+ The total allowed size for an intermediary tensor.
+ path_cost : int
+ The contraction cost so far.
+ naive_cost : int
+ The cost of the unoptimized expression.
+ cost : (int, int)
+ A tuple containing the size of any indices removed, and the flop cost.
+ new_input_sets : list of sets
+ The resulting new list of indices if this proposed contraction is performed.
+ contract = _find_contraction(positions, input_sets, output_set)
+ idx_result, new_input_sets, idx_removed, idx_contract = contract
+ new_size = _compute_size_by_dict(idx_result, idx_dict)
+ # Build sort tuple
+ old_sizes = (_compute_size_by_dict(input_sets[p], idx_dict) for p in positions)
+ removed_size = sum(old_sizes) - new_size
+ # NB: removed_size used to be just the size of any removed indices i.e.:
+ # helpers.compute_size_by_dict(idx_removed, idx_dict)
+ cost = _flop_count(idx_contract, idx_removed, len(positions), idx_dict)
+ sort = (-removed_size, cost)
+ # Sieve based on total cost as well
+ if (path_cost + cost) > naive_cost:
+ # Add contraction to possible choices
+ return [sort, positions, new_input_sets]
+def _update_other_results(results, best):
+ """Update the positions and provisional input_sets of ``results`` based on
+ performing the contraction result ``best``. Remove any involving the tensors
+ contracted.
+ results : list
+ List of contraction results produced by ``_parse_possible_contraction``.
+ best : list
+ The best contraction of ``results`` i.e. the one that will be performed.
+ mod_results : list
+ The list of modified results, updated with outcome of ``best`` contraction.
+ best_con = best[1]
+ bx, by = best_con
+ mod_results = []
+ for cost, (x, y), con_sets in results:
+ # Ignore results involving tensors just contracted
+ if x in best_con or y in best_con:
+ # Update the input_sets
+ del con_sets[by - int(by > x) - int(by > y)]
+ del con_sets[bx - int(bx > x) - int(bx > y)]
+ con_sets.insert(-1, best[2][-1])
+ # Update the position indices
+ mod_con = x - int(x > bx) - int(x > by), y - int(y > bx) - int(y > by)
+ mod_results.append((cost, mod_con, con_sets))
+ return mod_results
+def _greedy_path(input_sets, output_set, idx_dict, memory_limit):
+ Finds the path by contracting the best pair until the input list is
+ exhausted. The best pair is found by minimizing the tuple
+ ``(-prod(indices_removed), cost)``. What this amounts to is prioritizing
+ matrix multiplication or inner product operations, then Hadamard like
+ operations, and finally outer operations. Outer products are limited by
+ ``memory_limit``. This algorithm scales cubically with respect to the
+ number of elements in the list ``input_sets``.
+ memory_limit_limit : int
+ The greedy contraction order within the memory limit constraint.
+ >>> _greedy_path(isets, oset, idx_sizes, 5000)
+ # Handle trivial cases that leaked through
+ if len(input_sets) == 1:
+ return [(0,)]
+ elif len(input_sets) == 2:
+ return [(0, 1)]
+ # Build up a naive cost
+ contract = _find_contraction(range(len(input_sets)), input_sets, output_set)
+ naive_cost = _flop_count(idx_contract, idx_removed, len(input_sets), idx_dict)
+ # Initially iterate over all pairs
+ comb_iter = itertools.combinations(range(len(input_sets)), 2)
+ known_contractions = []
+ path_cost = 0
+ path = []
+ # Iterate over all pairs on first step, only previously found pairs on subsequent steps
+ for positions in comb_iter:
+ # Always initially ignore outer products
+ if input_sets[positions[0]].isdisjoint(input_sets[positions[1]]):
+ result = _parse_possible_contraction(positions, input_sets, output_set, idx_dict, memory_limit, path_cost,
+ naive_cost)
+ if result is not None:
+ known_contractions.append(result)
+ # If we do not have a inner contraction, rescan pairs including outer products
+ if len(known_contractions) == 0:
+ # Then check the outer products
+ for positions in itertools.combinations(range(len(input_sets)), 2):
+ result = _parse_possible_contraction(positions, input_sets, output_set, idx_dict, memory_limit,
+ path_cost, naive_cost)
+ # If we still did not find any remaining contractions, default back to einsum like behavior
+ path.append(tuple(range(len(input_sets))))
+ # Sort based on first index
+ best = min(known_contractions, key=lambda x: x[0])
+ # Now propagate as many unused contractions as possible to next iteration
+ known_contractions = _update_other_results(known_contractions, best)
+ # Next iteration only compute contractions with the new tensor
+ # All other contractions have been accounted for
+ input_sets = best[2]
+ new_tensor_pos = len(input_sets) - 1
+ comb_iter = ((i, new_tensor_pos) for i in range(new_tensor_pos))
+ # Update path and total cost
+ path.append(best[1])
+ path_cost += best[0][1]
+def _can_dot(inputs, result, idx_removed):
+ Checks if we can use BLAS (np.tensordot) call and its beneficial to do so.
+ inputs : list of str
+ Specifies the subscripts for summation.
+ result : str
+ Resulting summation.
+ Indices that are removed in the summation
+ type : bool
+ Returns true if BLAS should and can be used, else False
+ If the operations is BLAS level 1 or 2 and is not already aligned
+ we default back to einsum as the memory movement to copy is more
+ costly than the operation itself.
+ # Standard GEMM operation
+ >>> _can_dot(['ij', 'jk'], 'ik', set('j'))
+ # Can use the standard BLAS, but requires odd data movement
+ >>> _can_dot(['ijj', 'jk'], 'ik', set('j'))
+ # DDOT where the memory is not aligned
+ >>> _can_dot(['ijk', 'ikj'], '', set('ijk'))
+ # All `dot` calls remove indices
+ if len(idx_removed) == 0:
+ # BLAS can only handle two operands
+ if len(inputs) != 2:
+ input_left, input_right = inputs
+ for c in set(input_left + input_right):
+ # can't deal with repeated indices on same input or more than 2 total
+ nl, nr = input_left.count(c), input_right.count(c)
+ if (nl > 1) or (nr > 1) or (nl + nr > 2):
+ # can't do implicit summation or dimension collapse e.g.
+ # "ab,bc->c" (implicitly sum over 'a')
+ # "ab,ca->ca" (take diagonal of 'a')
+ if nl + nr - 1 == int(c in result):
+ # Build a few temporaries
+ set_left = set(input_left)
+ set_right = set(input_right)
+ keep_left = set_left - idx_removed
+ keep_right = set_right - idx_removed
+ rs = len(idx_removed)
+ # At this point we are a DOT, GEMV, or GEMM operation
+ # Handle inner products
+ # DDOT with aligned data
+ if input_left == input_right:
+ # DDOT without aligned data (better to use einsum)
+ if set_left == set_right:
+ # Handle the 4 possible (aligned) GEMV or GEMM cases
+ # GEMM or GEMV no transpose
+ if input_left[-rs:] == input_right[:rs]:
+ # GEMM or GEMV transpose both
+ if input_left[:rs] == input_right[-rs:]:
+ # GEMM or GEMV transpose right
+ if input_left[-rs:] == input_right[-rs:]:
+ # GEMM or GEMV transpose left
+ if input_left[:rs] == input_right[:rs]:
+ # Einsum is faster than GEMV if we have to copy data
+ if not keep_left or not keep_right:
+ # We are a matrix-matrix product, but we need to copy data
+def _parse_einsum_input(operands):
+ A reproduction of einsum c side einsum parsing in python.
+ input_strings : str
+ Parsed input strings
+ output_string : str
+ Parsed output string
+ The operands to use in the numpy contraction
+ The operand list is simplified to reduce printing:
+ >>> a = np.random.rand(4, 4)
+ >>> b = np.random.rand(4, 4, 4)
+ >>> _parse_einsum_input(('...a,...a->...', a, b))
+ ('za,xza', 'xz', [a, b]) # may vary
+ >>> _parse_einsum_input((a, [Ellipsis, 0], b, [Ellipsis, 0]))
+ if len(operands) == 0:
+ raise ValueError("No input operands")
+ if isinstance(operands[0], str):
+ subscripts = operands[0].replace(" ", "")
+ operands = [asanyarray(v) for v in operands[1:]]
+ # Ensure all characters are valid
+ for s in subscripts:
+ if s in '.,->':
+ if s not in einsum_symbols:
+ raise ValueError("Character %s is not a valid symbol." % s)
+ tmp_operands = list(operands)
+ operand_list = []
+ subscript_list = []
+ for p in range(len(operands) // 2):
+ operand_list.append(tmp_operands.pop(0))
+ subscript_list.append(tmp_operands.pop(0))
+ output_list = tmp_operands[-1] if len(tmp_operands) else None
+ operands = [asanyarray(v) for v in operand_list]
+ subscripts = ""
+ last = len(subscript_list) - 1
+ for num, sub in enumerate(subscript_list):
+ for s in sub:
+ if s is Ellipsis:
+ subscripts += "..."
+ s = operator.index(s)
+ except TypeError as e:
+ raise TypeError("For this input type lists must contain "
+ "either int or Ellipsis") from e
+ subscripts += einsum_symbols[s]
+ if num != last:
+ subscripts += ","
+ if output_list is not None:
+ subscripts += "->"
+ for s in output_list:
+ # Check for proper "->"
+ if ("-" in subscripts) or (">" in subscripts):
+ invalid = (subscripts.count("-") > 1) or (subscripts.count(">") > 1)
+ if invalid or (subscripts.count("->") != 1):
+ raise ValueError("Subscripts can only contain one '->'.")
+ # Parse ellipses
+ if "." in subscripts:
+ used = subscripts.replace(".", "").replace(",", "").replace("->", "")
+ unused = list(einsum_symbols_set - set(used))
+ ellipse_inds = "".join(unused)
+ longest = 0
+ if "->" in subscripts:
+ input_tmp, output_sub = subscripts.split("->")
+ split_subscripts = input_tmp.split(",")
+ out_sub = True
+ split_subscripts = subscripts.split(',')
+ out_sub = False
+ for num, sub in enumerate(split_subscripts):
+ if "." in sub:
+ if (sub.count(".") != 3) or (sub.count("...") != 1):
+ raise ValueError("Invalid Ellipses.")
+ # Take into account numerical values
+ if operands[num].shape == ():
+ ellipse_count = 0
+ ellipse_count = max(operands[num].ndim, 1)
+ ellipse_count -= (len(sub) - 3)
+ if ellipse_count > longest:
+ longest = ellipse_count
+ if ellipse_count < 0:
+ raise ValueError("Ellipses lengths do not match.")
+ elif ellipse_count == 0:
+ split_subscripts[num] = sub.replace('...', '')
+ rep_inds = ellipse_inds[-ellipse_count:]
+ split_subscripts[num] = sub.replace('...', rep_inds)
+ subscripts = ",".join(split_subscripts)
+ if longest == 0:
+ out_ellipse = ""
+ out_ellipse = ellipse_inds[-longest:]
+ if out_sub:
+ subscripts += "->" + output_sub.replace("...", out_ellipse)
+ # Special care for outputless ellipses
+ output_subscript = ""
+ tmp_subscripts = subscripts.replace(",", "")
+ for s in sorted(set(tmp_subscripts)):
+ if s not in (einsum_symbols):
+ if tmp_subscripts.count(s) == 1:
+ output_subscript += s
+ normal_inds = ''.join(sorted(set(output_subscript) -
+ set(out_ellipse)))
+ subscripts += "->" + out_ellipse + normal_inds
+ # Build output string if does not exist
+ input_subscripts, output_subscript = subscripts.split("->")
+ input_subscripts = subscripts
+ # Build output subscripts
+ # Make sure output subscripts are in the input
+ for char in output_subscript:
+ if char not in input_subscripts:
+ raise ValueError("Output character %s did not appear in the input"
+ % char)
+ # Make sure number operands is equivalent to the number of terms
+ if len(input_subscripts.split(',')) != len(operands):
+ raise ValueError("Number of einsum subscripts must be equal to the "
+ "number of operands.")
+ return (input_subscripts, output_subscript, operands)
+def _einsum_path_dispatcher(*operands, optimize=None, einsum_call=None):
+ # NOTE: technically, we should only dispatch on array-like arguments, not
+ # subscripts (given as strings). But separating operands into
+ # arrays/subscripts is a little tricky/slow (given einsum's two supported
+ # signatures), so as a practical shortcut we dispatch on everything.
+ # Strings will be ignored for dispatching since they don't define
+ # __array_function__.
+ return operands
+@array_function_dispatch(_einsum_path_dispatcher, module='numpy')
+def einsum_path(*operands, optimize='greedy', einsum_call=False):
+ einsum_path(subscripts, *operands, optimize='greedy')
+ Evaluates the lowest cost contraction order for an einsum expression by
+ considering the creation of intermediate arrays.
+ *operands : list of array_like
+ optimize : {bool, list, tuple, 'greedy', 'optimal'}
+ Choose the type of path. If a tuple is provided, the second argument is
+ assumed to be the maximum intermediate size created. If only a single
+ argument is provided the largest input or output array size is used
+ as a maximum intermediate size.
+ * if a list is given that starts with ``einsum_path``, uses this as the
+ contraction path
+ * if False no optimization is taken
+ * if True defaults to the 'greedy' algorithm
+ * 'optimal' An algorithm that combinatorially explores all possible
+ ways of contracting the listed tensors and choosest the least costly
+ path. Scales exponentially with the number of terms in the
+ contraction.
+ * 'greedy' An algorithm that chooses the best pair contraction
+ at each step. Effectively, this algorithm searches the largest inner,
+ Hadamard, and then outer products at each step. Scales cubically with
+ the number of terms in the contraction. Equivalent to the 'optimal'
+ path for most contractions.
+ Default is 'greedy'.
+ path : list of tuples
+ A list representation of the einsum path.
+ string_repr : str
+ A printable representation of the einsum path.
+ The resulting path indicates which terms of the input contraction should be
+ contracted first, the result of this contraction is then appended to the
+ end of the contraction list. This list can then be iterated over until all
+ intermediate contractions are complete.
+ einsum, linalg.multi_dot
+ We can begin with a chain dot example. In this case, it is optimal to
+ contract the ``b`` and ``c`` tensors first as represented by the first
+ element of the path ``(1, 2)``. The resulting tensor is added to the end
+ of the contraction and the remaining contraction ``(0, 1)`` is then
+ completed.
+ >>> a = np.random.rand(2, 2)
+ >>> b = np.random.rand(2, 5)
+ >>> c = np.random.rand(5, 2)
+ >>> path_info = np.einsum_path('ij,jk,kl->il', a, b, c, optimize='greedy')
+ >>> print(path_info[0])
+ ['einsum_path', (1, 2), (0, 1)]
+ >>> print(path_info[1])
+ Complete contraction: ij,jk,kl->il # may vary
+ Naive scaling: 4
+ Optimized scaling: 3
+ Naive FLOP count: 1.600e+02
+ Optimized FLOP count: 5.600e+01
+ Theoretical speedup: 2.857
+ Largest intermediate: 4.000e+00 elements
+ -------------------------------------------------------------------------
+ scaling current remaining
+ 3 kl,jk->jl ij,jl->il
+ 3 jl,ij->il il->il
+ A more complex index transformation example.
+ >>> I = np.random.rand(10, 10, 10, 10)
+ >>> C = np.random.rand(10, 10)
+ >>> path_info = np.einsum_path('ea,fb,abcd,gc,hd->efgh', C, C, I, C, C,
+ ... optimize='greedy')
+ ['einsum_path', (0, 2), (0, 3), (0, 2), (0, 1)]
+ Complete contraction: ea,fb,abcd,gc,hd->efgh # may vary
+ Naive scaling: 8
+ Optimized scaling: 5
+ Naive FLOP count: 8.000e+08
+ Optimized FLOP count: 8.000e+05
+ Theoretical speedup: 1000.000
+ Largest intermediate: 1.000e+04 elements
+ --------------------------------------------------------------------------
+ 5 abcd,ea->bcde fb,gc,hd,bcde->efgh
+ 5 bcde,fb->cdef gc,hd,cdef->efgh
+ 5 cdef,gc->defg hd,defg->efgh
+ 5 defg,hd->efgh efgh->efgh
+ # Figure out what the path really is
+ path_type = optimize
+ if path_type is True:
+ path_type = 'greedy'
+ if path_type is None:
+ path_type = False
+ memory_limit = None
+ # No optimization or a named path algorithm
+ if (path_type is False) or isinstance(path_type, str):
+ # Given an explicit path
+ elif len(path_type) and (path_type[0] == 'einsum_path'):
+ # Path tuple with memory limit
+ elif ((len(path_type) == 2) and isinstance(path_type[0], str) and
+ isinstance(path_type[1], (int, float))):
+ memory_limit = int(path_type[1])
+ path_type = path_type[0]
+ raise TypeError("Did not understand the path: %s" % str(path_type))
+ # Hidden option, only einsum should call this
+ einsum_call_arg = einsum_call
+ # Python side parsing
+ input_subscripts, output_subscript, operands = _parse_einsum_input(operands)
+ # Build a few useful list and sets
+ input_list = input_subscripts.split(',')
+ input_sets = [set(x) for x in input_list]
+ output_set = set(output_subscript)
+ indices = set(input_subscripts.replace(',', ''))
+ # Get length of each unique dimension and ensure all dimensions are correct
+ dimension_dict = {}
+ broadcast_indices = [[] for x in range(len(input_list))]
+ for tnum, term in enumerate(input_list):
+ sh = operands[tnum].shape
+ if len(sh) != len(term):
+ raise ValueError("Einstein sum subscript %s does not contain the "
+ "correct number of indices for operand %d."
+ % (input_subscripts[tnum], tnum))
+ for cnum, char in enumerate(term):
+ dim = sh[cnum]
+ # Build out broadcast indices
+ if dim == 1:
+ broadcast_indices[tnum].append(char)
+ if char in dimension_dict.keys():
+ # For broadcasting cases we always want the largest dim size
+ if dimension_dict[char] == 1:
+ dimension_dict[char] = dim
+ elif dim not in (1, dimension_dict[char]):
+ raise ValueError("Size of label '%s' for operand %d (%d) "
+ "does not match previous terms (%d)."
+ % (char, tnum, dimension_dict[char], dim))
+ # Convert broadcast inds to sets
+ broadcast_indices = [set(x) for x in broadcast_indices]
+ # Compute size of each input array plus the output array
+ size_list = [_compute_size_by_dict(term, dimension_dict)
+ for term in input_list + [output_subscript]]
+ max_size = max(size_list)
+ if memory_limit is None:
+ memory_arg = max_size
+ memory_arg = memory_limit
+ # Compute naive cost
+ # This isn't quite right, need to look into exactly how einsum does this
+ inner_product = (sum(len(x) for x in input_sets) - len(indices)) > 0
+ naive_cost = _flop_count(indices, inner_product, len(input_list), dimension_dict)
+ # Compute the path
+ if (path_type is False) or (len(input_list) in [1, 2]) or (indices == output_set):
+ # Nothing to be optimized, leave it to einsum
+ path = [tuple(range(len(input_list)))]
+ elif path_type == "greedy":
+ path = _greedy_path(input_sets, output_set, dimension_dict, memory_arg)
+ elif path_type == "optimal":
+ path = _optimal_path(input_sets, output_set, dimension_dict, memory_arg)
+ elif path_type[0] == 'einsum_path':
+ path = path_type[1:]
+ raise KeyError("Path name %s not found", path_type)
+ cost_list, scale_list, size_list, contraction_list = [], [], [], []
+ # Build contraction tuple (positions, gemm, einsum_str, remaining)
+ for cnum, contract_inds in enumerate(path):
+ # Make sure we remove inds from right to left
+ contract_inds = tuple(sorted(list(contract_inds), reverse=True))
+ contract = _find_contraction(contract_inds, input_sets, output_set)
+ out_inds, input_sets, idx_removed, idx_contract = contract
+ cost = _flop_count(idx_contract, idx_removed, len(contract_inds), dimension_dict)
+ cost_list.append(cost)
+ scale_list.append(len(idx_contract))
+ size_list.append(_compute_size_by_dict(out_inds, dimension_dict))
+ bcast = set()
+ tmp_inputs = []
+ for x in contract_inds:
+ tmp_inputs.append(input_list.pop(x))
+ bcast |= broadcast_indices.pop(x)
+ new_bcast_inds = bcast - idx_removed
+ # If we're broadcasting, nix blas
+ if not len(idx_removed & bcast):
+ do_blas = _can_dot(tmp_inputs, out_inds, idx_removed)
+ do_blas = False
+ # Last contraction
+ if (cnum - len(path)) == -1:
+ idx_result = output_subscript
+ sort_result = [(dimension_dict[ind], ind) for ind in out_inds]
+ idx_result = "".join([x[1] for x in sorted(sort_result)])
+ input_list.append(idx_result)
+ broadcast_indices.append(new_bcast_inds)
+ einsum_str = ",".join(tmp_inputs) + "->" + idx_result
+ contraction = (contract_inds, idx_removed, einsum_str, input_list[:], do_blas)
+ contraction_list.append(contraction)
+ opt_cost = sum(cost_list) + 1
+ if einsum_call_arg:
+ return (operands, contraction_list)
+ # Return the path along with a nice string representation
+ overall_contraction = input_subscripts + "->" + output_subscript
+ header = ("scaling", "current", "remaining")
+ speedup = naive_cost / opt_cost
+ max_i = max(size_list)
+ path_print = " Complete contraction: %s\n" % overall_contraction
+ path_print += " Naive scaling: %d\n" % len(indices)
+ path_print += " Optimized scaling: %d\n" % max(scale_list)
+ path_print += " Naive FLOP count: %.3e\n" % naive_cost
+ path_print += " Optimized FLOP count: %.3e\n" % opt_cost
+ path_print += " Theoretical speedup: %3.3f\n" % speedup
+ path_print += " Largest intermediate: %.3e elements\n" % max_i
+ path_print += "-" * 74 + "\n"
+ path_print += "%6s %24s %40s\n" % header
+ path_print += "-" * 74
+ for n, contraction in enumerate(contraction_list):
+ inds, idx_rm, einsum_str, remaining, blas = contraction
+ remaining_str = ",".join(remaining) + "->" + output_subscript
+ path_run = (scale_list[n], einsum_str, remaining_str)
+ path_print += "\n%4d %24s %40s" % path_run
+ path = ['einsum_path'] + path
+ return (path, path_print)
+def _einsum_dispatcher(*operands, out=None, optimize=None, **kwargs):
+ # Arguably we dispatch on more arguments that we really should; see note in
+ # _einsum_path_dispatcher for why.
+ yield from operands
+ yield out
+# Rewrite einsum to handle different cases
+@array_function_dispatch(_einsum_dispatcher, module='numpy')
+def einsum(*operands, out=None, optimize=False, **kwargs):
+ einsum(subscripts, *operands, out=None, dtype=None, order='K',
+ casting='safe', optimize=False)
+ 'K' means it should be as close to the layout as the inputs as
+ 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 <https://optimized-einsum.readthedocs.io/en/stable/>`_
+ optimizes contraction order for einsum-like expressions
+ in backend-agnostic manner.
+ Added the ``optimize`` argument which will optimize the contraction order
+ of an einsum expression. For a contraction with three or more operands this
+ can greatly increase the computational efficiency at the cost of a larger
+ memory footprint during computation.
+ Typically a 'greedy' algorithm is applied which empirical tests have shown
+ returns the optimal path in the majority of cases. In some cases 'optimal'
+ will return the superlative path through a more expensive, exhaustive search.
+ For iterative calculations it may be advisable to calculate the optimal path
+ once and reuse that path by supplying it as an argument. An example is given
+ below.
+ See :py:func:`numpy.einsum_path` for more details.
+ array([[4400., 4730.],
+ [4532., 4874.],
+ [4664., 5018.],
+ [4796., 5162.],
+ [4928., 5306.]])
+ Chained array operations. For more complicated contractions, speed ups
+ might be achieved by repeatedly computing a 'greedy' path or pre-computing the
+ 'optimal' path and repeatedly applying it, using an
+ `einsum_path` insertion (since version 1.12.0). Performance improvements can be
+ particularly significant with larger arrays:
+ >>> a = np.ones(64).reshape(2,4,8)
+ Basic `einsum`: ~1520ms (benchmarked on 3.1GHz Intel i5.)
+ >>> for iteration in range(500):
+ ... _ = np.einsum('ijk,ilm,njm,nlk,abc->',a,a,a,a,a)
+ Sub-optimal `einsum` (due to repeated path calculation time): ~330ms
+ ... _ = np.einsum('ijk,ilm,njm,nlk,abc->',a,a,a,a,a, optimize='optimal')
+ Greedy `einsum` (faster optimal path approximation): ~160ms
+ ... _ = np.einsum('ijk,ilm,njm,nlk,abc->',a,a,a,a,a, optimize='greedy')
+ Optimal `einsum` (best usage pattern in some use cases): ~110ms
+ >>> path = np.einsum_path('ijk,ilm,njm,nlk,abc->',a,a,a,a,a, optimize='optimal')[0]
+ ... _ = np.einsum('ijk,ilm,njm,nlk,abc->',a,a,a,a,a, optimize=path)
+ # Special handling if out is specified
+ specified_out = out is not None
+ # If no optimization, run pure einsum
+ if optimize is False:
+ if specified_out:
+ kwargs['out'] = out
+ return c_einsum(*operands, **kwargs)
+ # Check the kwargs to avoid a more cryptic error later, without having to
+ # repeat default values here
+ valid_einsum_kwargs = ['dtype', 'order', 'casting']
+ unknown_kwargs = [k for (k, v) in kwargs.items() if
+ k not in valid_einsum_kwargs]
+ if len(unknown_kwargs):
+ raise TypeError("Did not understand the following kwargs: %s"
+ % unknown_kwargs)
+ # Build the contraction list and operand
+ operands, contraction_list = einsum_path(*operands, optimize=optimize,
+ einsum_call=True)
+ # Handle order kwarg for output array, c_einsum allows mixed case
+ output_order = kwargs.pop('order', 'K')
+ if output_order.upper() == 'A':
+ if all(arr.flags.f_contiguous for arr in operands):
+ output_order = 'F'
+ output_order = 'C'
+ # Start contraction loop
+ for num, contraction in enumerate(contraction_list):
+ tmp_operands = [operands.pop(x) for x in inds]
+ # Do we need to deal with the output?
+ handle_out = specified_out and ((num + 1) == len(contraction_list))
+ # Call tensordot if still possible
+ if blas:
+ # Checks have already been handled
+ input_str, results_index = einsum_str.split('->')
+ input_left, input_right = input_str.split(',')
+ tensor_result = input_left + input_right
+ for s in idx_rm:
+ tensor_result = tensor_result.replace(s, "")
+ # Find indices to contract over
+ left_pos, right_pos = [], []
+ for s in sorted(idx_rm):
+ left_pos.append(input_left.find(s))
+ right_pos.append(input_right.find(s))
+ # Contract!
+ new_view = tensordot(*tmp_operands, axes=(tuple(left_pos), tuple(right_pos)))
+ # Build a new view if needed
+ if (tensor_result != results_index) or handle_out:
+ if handle_out:
+ kwargs["out"] = out
+ new_view = c_einsum(tensor_result + '->' + results_index, new_view, **kwargs)
+ # Call einsum
+ # If out was specified
+ # Do the contraction
+ new_view = c_einsum(einsum_str, *tmp_operands, **kwargs)
+ # Append new items and dereference what we can
+ operands.append(new_view)
+ del tmp_operands, new_view
+ return out
+ return asanyarray(operands[0], order=output_order)
@@ -0,0 +1,3768 @@
+"""Module containing non-deprecated functions borrowed from Numeric.
+from . import multiarray as mu
+from . import overrides
+from . import umath as um
+from ._asarray import asarray, array, asanyarray
+from .multiarray import concatenate
+_dt_ = nt.sctype2char
+# functions that are methods
+ 'alen', 'all', 'alltrue', 'amax', 'amin', 'any', 'argmax',
+ 'argmin', 'argpartition', 'argsort', 'around', 'choose', 'clip',
+ 'compress', 'cumprod', 'cumproduct', 'cumsum', 'diagonal', 'mean',
+ 'ndim', 'nonzero', 'partition', 'prod', 'product', 'ptp', 'put',
+ 'ravel', 'repeat', 'reshape', 'resize', 'round_',
+ 'searchsorted', 'shape', 'size', 'sometrue', 'sort', 'squeeze',
+ 'std', 'sum', 'swapaxes', 'take', 'trace', 'transpose', 'var',
+_gentype = types.GeneratorType
+# save away Python sum
+_sum_ = sum
+ overrides.array_function_dispatch, module='numpy')
+# functions that are now methods
+def _wrapit(obj, method, *args, **kwds):
+ wrap = obj.__array_wrap__
+ wrap = None
+ result = getattr(asarray(obj), method)(*args, **kwds)
+ if wrap:
+ if not isinstance(result, mu.ndarray):
+ result = asarray(result)
+ result = wrap(result)
+def _wrapfunc(obj, method, *args, **kwds):
+ bound = getattr(obj, method, None)
+ if bound is None:
+ return _wrapit(obj, method, *args, **kwds)
+ return bound(*args, **kwds)
+ # A TypeError occurs if the object does have such a method in its
+ # class, but its signature is not identical to that of NumPy's. This
+ # situation has occurred in the case of a downstream library like
+ # 'pandas'.
+ # Call _wrapit from within the except clause to ensure a potential
+ # exception has a traceback chain.
+def _wrapreduction(obj, ufunc, method, axis, dtype, out, **kwargs):
+ passkwargs = {k: v for k, v in kwargs.items()
+ if v is not np._NoValue}
+ if type(obj) is not mu.ndarray:
+ reduction = getattr(obj, method)
+ # This branch is needed for reductions like any which don't
+ # support a dtype.
+ if dtype is not None:
+ return reduction(axis=axis, dtype=dtype, out=out, **passkwargs)
+ return reduction(axis=axis, out=out, **passkwargs)
+ return ufunc.reduce(obj, axis, dtype, out, **passkwargs)
+def _take_dispatcher(a, indices, axis=None, out=None, mode=None):
+ return (a, out)
+@array_function_dispatch(_take_dispatcher)
+def take(a, indices, axis=None, out=None, mode='raise'):
+ Take elements from an array along an axis.
+ When axis is not None, this function does the same thing as "fancy"
+ indexing (indexing arrays using arrays); however, it can be easier to use
+ if you need elements along a given axis. A call such as
+ ``np.take(arr, indices, axis=3)`` is equivalent to
+ ``arr[:,:,:,indices,...]``.
+ Explained without fancy indexing, this is equivalent to the following use
+ of `ndindex`, which sets each of ``ii``, ``jj``, and ``kk`` to a tuple of
+ indices::
+ Ni, Nk = a.shape[:axis], a.shape[axis+1:]
+ Nj = indices.shape
+ for ii in ndindex(Ni):
+ for jj in ndindex(Nj):
+ for kk in ndindex(Nk):
+ out[ii + jj + kk] = a[ii + (indices[jj],) + kk]
+ a : array_like (Ni..., M, Nk...)
+ The source array.
+ indices : array_like (Nj...)
+ The indices of the values to extract.
+ Also allow scalars for indices.
+ The axis over which to select values. By default, the flattened
+ input array is used.
+ out : ndarray, optional (Ni..., Nj..., Nk...)
+ If provided, the result will be placed in 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.
+ mode : {'raise', 'wrap', 'clip'}, optional
+ Specifies how out-of-bounds indices will behave.
+ * 'raise' -- raise an error (default)
+ * 'wrap' -- wrap around
+ * 'clip' -- clip to the range
+ 'clip' mode means that all indices that are too large are replaced
+ by the index that addresses the last element along that axis. Note
+ that this disables indexing with negative numbers.
+ out : ndarray (Ni..., Nj..., Nk...)
+ The returned array has the same type as `a`.
+ compress : Take elements using a boolean mask
+ ndarray.take : equivalent method
+ take_along_axis : Take elements by matching the array and the index arrays
+ By eliminating the inner loop in the description above, and using `s_` to
+ build simple slice objects, `take` can be expressed in terms of applying
+ fancy indexing to each 1-d slice::
+ for kk in ndindex(Nj):
+ out[ii + s_[...,] + kk] = a[ii + s_[:,] + kk][indices]
+ For this reason, it is equivalent to (but faster than) the following use
+ of `apply_along_axis`::
+ out = np.apply_along_axis(lambda a_1d: a_1d[indices], axis, a)
+ >>> a = [4, 3, 5, 7, 6, 8]
+ >>> indices = [0, 1, 4]
+ >>> np.take(a, indices)
+ array([4, 3, 6])
+ In this example if `a` is an ndarray, "fancy" indexing can be used.
+ >>> a = np.array(a)
+ >>> a[indices]
+ If `indices` is not one dimensional, the output also has these dimensions.
+ >>> np.take(a, [[0, 1], [2, 3]])
+ array([[4, 3],
+ [5, 7]])
+ return _wrapfunc(a, 'take', indices, axis=axis, out=out, mode=mode)
+def _reshape_dispatcher(a, newshape, order=None):
+# not deprecated --- copy if necessary, view otherwise
+@array_function_dispatch(_reshape_dispatcher)
+def reshape(a, newshape, order='C'):
+ Gives a new shape to an array without changing its data.
+ Array to be reshaped.
+ newshape : int or tuple of ints
+ The new shape should be compatible with the original shape. If
+ an integer, then the result will be a 1-D array of that length.
+ One shape dimension can be -1. In this case, the value is
+ inferred from the length of the array and remaining dimensions.
+ Read the elements of `a` using this index order, and place the
+ elements into the reshaped array using this index order. 'C'
+ means to read / write the elements using C-like index order,
+ with the last axis index changing fastest, back to the first
+ axis index changing slowest. 'F' means to read / write the
+ elements using Fortran-like index order, with the first index
+ changing fastest, and the last index changing slowest. Note that
+ the 'C' and 'F' options take no account of the memory layout of
+ the underlying array, and only refer to the order of indexing.
+ 'A' means to read / write the elements in Fortran-like index
+ order if `a` is Fortran *contiguous* in memory, C-like order
+ reshaped_array : ndarray
+ This will be a new view object if possible; otherwise, it will
+ be a copy. Note there is no guarantee of the *memory layout* (C- or
+ Fortran- contiguous) of the returned array.
+ ndarray.reshape : Equivalent method.
+ It is not always possible to change the shape of an array without
+ copying the data. If you want an error to be raised when the data is copied,
+ you should assign the new shape to the shape attribute of the array::
+ >>> a = np.zeros((10, 2))
+ # A transpose makes the array non-contiguous
+ >>> b = a.T
+ # Taking a view makes it possible to modify the shape without modifying
+ # the initial object.
+ >>> c = b.view()
+ >>> c.shape = (20)
+ The `order` keyword gives the index ordering both for *fetching* the values
+ from `a`, and then *placing* the values into the output array.
+ For example, let's say you have an array:
+ >>> a = np.arange(6).reshape((3, 2))
+ [2, 3],
+ [4, 5]])
+ You can think of reshaping as first raveling the array (using the given
+ index order), then inserting the elements from the raveled array into the
+ new array using the same kind of index ordering as was used for the
+ raveling.
+ >>> np.reshape(a, (2, 3)) # C-like index ordering
+ >>> np.reshape(np.ravel(a), (2, 3)) # equivalent to C ravel then C reshape
+ >>> np.reshape(a, (2, 3), order='F') # Fortran-like index ordering
+ array([[0, 4, 3],
+ [2, 1, 5]])
+ >>> np.reshape(np.ravel(a, order='F'), (2, 3), order='F')
+ >>> a = np.array([[1,2,3], [4,5,6]])
+ >>> np.reshape(a, 6)
+ array([1, 2, 3, 4, 5, 6])
+ >>> np.reshape(a, 6, order='F')
+ array([1, 4, 2, 5, 3, 6])
+ >>> np.reshape(a, (3,-1)) # the unspecified value is inferred to be 2
+ [3, 4],
+ [5, 6]])
+ return _wrapfunc(a, 'reshape', newshape, order=order)
+def _choose_dispatcher(a, choices, out=None, mode=None):
+ yield a
+ yield from choices
+@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.
+ First of all, if confused or uncertain, definitely look at the Examples -
+ in its full generality, this function is less simple than it might
+ seem from the following code description (below ndi =
+ `numpy.lib.index_tricks`):
+ ``np.choose(a,c) == np.array([c[a[I]][I] for I in ndi.ndindex(a.shape)])``.
+ But this omits some subtleties. Here is a fully general summary:
+ 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
+ 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=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.
+ 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.
+ 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
+ its outermost dimension (i.e., the one corresponding to
+ ``choices.shape[0]``) is taken as defining the "sequence".
+ out : array, optional
+ If provided, the result will be inserted into this array. It should
+ mode : {'raise' (default), 'wrap', 'clip'}, optional
+ Specifies how indices outside `[0, n-1]` will be treated:
+ * 'raise' : an exception is raised
+ * 'wrap' : value becomes value mod `n`
+ * 'clip' : values < 0 are mapped to 0, values > n-1 are mapped to n-1
+ merged_array : array
+ The merged result.
+ ValueError: shape mismatch
+ If `a` and each choice array are not all broadcastable to the same
+ shape.
+ ndarray.choose : equivalent method
+ numpy.take_along_axis : Preferable if `choices` is an array
+ To reduce the chance of misinterpretation, even though the following
+ "abuse" is nominally supported, `choices` should neither be, nor be
+ thought of as, a single array, i.e., the outermost sequence-like container
+ should be either a list or a tuple.
+ >>> choices = [[0, 1, 2, 3], [10, 11, 12, 13],
+ ... [20, 21, 22, 23], [30, 31, 32, 33]]
+ >>> np.choose([2, 3, 1, 0], choices
+ ... # the first element of the result will be the first element of the
+ ... # third (2+1) "array" in choices, namely, 20; the second element
+ ... # will be the second element of the fourth (3+1) choice array, i.e.,
+ ... # 31, etc.
+ ... )
+ array([20, 31, 12, 3])
+ >>> np.choose([2, 4, 1, 0], choices, mode='clip') # 4 goes to 3 (4-1)
+ >>> # because there are 4 choice arrays
+ >>> np.choose([2, 4, 1, 0], choices, mode='wrap') # 4 goes to (4 mod 4)
+ array([20, 1, 12, 3])
+ >>> # i.e., 0
+ A couple examples illustrating how choose broadcasts:
+ >>> a = [[1, 0, 1], [0, 1, 0], [1, 0, 1]]
+ >>> choices = [-10, 10]
+ >>> np.choose(a, choices)
+ array([[ 10, -10, 10],
+ [-10, 10, -10],
+ [ 10, -10, 10]])
+ >>> # With thanks to Anne Archibald
+ >>> a = np.array([0, 1]).reshape((2,1,1))
+ >>> c1 = np.array([1, 2, 3]).reshape((1,3,1))
+ >>> c2 = np.array([-1, -2, -3, -4, -5]).reshape((1,1,5))
+ >>> np.choose(a, (c1, c2)) # result is 2x3x5, res[0,:,:]=c1, res[1,:,:]=c2
+ array([[[ 1, 1, 1, 1, 1],
+ [ 2, 2, 2, 2, 2],
+ [ 3, 3, 3, 3, 3]],
+ [[-1, -2, -3, -4, -5],
+ [-1, -2, -3, -4, -5],
+ [-1, -2, -3, -4, -5]]])
+ return _wrapfunc(a, 'choose', choices, out=out, mode=mode)
+def _repeat_dispatcher(a, repeats, axis=None):
+@array_function_dispatch(_repeat_dispatcher)
+def repeat(a, repeats, axis=None):
+ repeats : int or array of ints
+ The number of repetitions for each element. `repeats` is broadcasted
+ to fit the shape of the given axis.
+ The axis along which to repeat values. By default, use the
+ flattened input array, and return a flat output array.
+ repeated_array : ndarray
+ Output array which has the same shape as `a`, except along
+ the given axis.
+ tile : Tile an array.
+ unique : Find the unique elements of an array.
+ >>> np.repeat(3, 4)
+ array([3, 3, 3, 3])
+ >>> x = np.array([[1,2],[3,4]])
+ >>> np.repeat(x, 2)
+ array([1, 1, 2, 2, 3, 3, 4, 4])
+ >>> np.repeat(x, 3, axis=1)
+ array([[1, 1, 1, 2, 2, 2],
+ [3, 3, 3, 4, 4, 4]])
+ >>> np.repeat(x, [1, 2], axis=0)
+ return _wrapfunc(a, 'repeat', repeats, axis=axis)
+def _put_dispatcher(a, ind, v, mode=None):
+ return (a, ind, v)
+@array_function_dispatch(_put_dispatcher)
+def put(a, ind, v, mode='raise'):
+ Replaces specified elements of an array with given values.
+ The indexing works on the flattened target array. `put` is roughly
+ a.flat[ind] = v
+ Target array.
+ ind : array_like
+ Target indices, interpreted as integers.
+ v : array_like
+ Values to place in `a` at target indices. If `v` is shorter than
+ `ind` it will be repeated as necessary.
+ that this disables indexing with negative numbers. In 'raise' mode,
+ if an exception occurs the target array may still be modified.
+ putmask, place
+ put_along_axis : Put elements by matching the array and the index arrays
+ >>> np.put(a, [0, 2], [-44, -55])
+ array([-44, 1, -55, 3, 4])
+ >>> np.put(a, 22, -5, mode='clip')
+ array([ 0, 1, 2, 3, -5])
+ put = a.put
+ except AttributeError as e:
+ raise TypeError("argument 1 must be numpy.ndarray, "
+ "not {name}".format(name=type(a).__name__)) from e
+ return put(ind, v, mode=mode)
+def _swapaxes_dispatcher(a, axis1, axis2):
+@array_function_dispatch(_swapaxes_dispatcher)
+def swapaxes(a, axis1, axis2):
+ Interchange two axes of an array.
+ axis1 : int
+ First axis.
+ axis2 : int
+ Second axis.
+ a_swapped : ndarray
+ For NumPy >= 1.10.0, if `a` is an ndarray, then a view of `a` is
+ returned; otherwise a new array is created. For earlier NumPy
+ versions a view of `a` is returned only if the order of the
+ axes is changed, otherwise the input array is returned.
+ >>> x = np.array([[1,2,3]])
+ >>> np.swapaxes(x,0,1)
+ array([[1],
+ [2],
+ [3]])
+ >>> x = np.array([[[0,1],[2,3]],[[4,5],[6,7]]])
+ >>> np.swapaxes(x,0,2)
+ array([[[0, 4],
+ [2, 6]],
+ [[1, 5],
+ [3, 7]]])
+ return _wrapfunc(a, 'swapaxes', axis1, axis2)
+def _transpose_dispatcher(a, axes=None):
+@array_function_dispatch(_transpose_dispatcher)
+def transpose(a, axes=None):
+ Reverse or permute the axes of an array; returns the modified array.
+ For an array a with two axes, transpose(a) gives the matrix transpose.
+ axes : tuple or list of ints, optional
+ If specified, it must be a tuple or list which contains a permutation of
+ [0,1,..,N-1] where N is the number of axes of a. The i'th axis of the
+ returned array will correspond to the axis numbered ``axes[i]`` of the
+ input. If not specified, defaults to ``range(a.ndim)[::-1]``, which
+ reverses the order of the axes.
+ p : ndarray
+ `a` with its axes permuted. A view is returned whenever
+ possible.
+ moveaxis
+ Use `transpose(a, argsort(axes))` to invert the transposition of tensors
+ when using the `axes` keyword argument.
+ Transposing a 1-D array returns an unchanged view of the original array.
+ >>> x = np.arange(4).reshape((2,2))
+ >>> np.transpose(x)
+ array([[0, 2],
+ >>> x = np.ones((1, 2, 3))
+ >>> np.transpose(x, (1, 0, 2)).shape
+ (2, 1, 3)
+ >>> x = np.ones((2, 3, 4, 5))
+ >>> np.transpose(x).shape
+ (5, 4, 3, 2)
+ return _wrapfunc(a, 'transpose', axes)
+def _partition_dispatcher(a, kth, axis=None, kind=None, order=None):
+def partition(a, kth, axis=-1, kind='introselect', order=None):
+ Return a partitioned copy of an array.
+ Creates a copy of the array with its elements rearranged in such a
+ way that the value of the element in k-th position is in the
+ position it would be in a sorted array. All elements smaller than
+ the k-th element are moved before this element and all equal or
+ greater are moved behind it. The ordering of the elements in the two
+ partitions is undefined.
+ Array to be sorted.
+ Element index to partition by. The k-th value of the element
+ will be in its final sorted position and all smaller elements
+ will be moved before it and all equal or greater elements behind
+ it. The order of all elements in the partitions is undefined. If
+ provided with a sequence of k-th it will partition all elements
+ indexed by k-th of them into their sorted position at once.
+ axis : int or None, optional
+ Axis along which to sort. If None, the array is flattened before
+ sorting. The default is -1, which sorts along the last axis.
+ When `a` is an array with fields defined, this argument
+ specifies which fields to compare first, second, etc. A single
+ field can be specified as a string. Not all fields need be
+ specified, but unspecified fields will still be used, in the
+ order in which they come up in the dtype, to break ties.
+ partitioned_array : ndarray
+ Array of the same type and shape as `a`.
+ ndarray.partition : Method to sort an array in-place.
+ sort : Full sorting
+ The various selection algorithms are characterized by their average
+ speed, worst case performance, work space size, and whether they are
+ stable. A stable sort keeps items with the same key in the same
+ relative order. The available algorithms have the following
+ properties:
+ ================= ======= ============= ============ =======
+ kind speed worst case work space stable
+ 'introselect' 1 O(n) 0 no
+ All the partition algorithms make temporary copies of the data when
+ partitioning along any but the last axis. Consequently,
+ partitioning along the last axis is faster and uses less space than
+ partitioning along any other axis.
+ The sort order for complex numbers is lexicographic. If both the
+ real and imaginary parts are non-nan then the order is determined by
+ the real parts except when they are equal, in which case the order
+ is determined by the imaginary parts.
+ >>> np.partition(a, 3)
+ >>> np.partition(a, (1, 3))
+ # flatten returns (1, N) for np.matrix, so always use the last axis
+ a = asanyarray(a).flatten()
+ axis = -1
+ a = asanyarray(a).copy(order="K")
+ a.partition(kth, axis=axis, kind=kind, order=order)
+def _argpartition_dispatcher(a, kth, axis=None, kind=None, order=None):
+@array_function_dispatch(_argpartition_dispatcher)
+def argpartition(a, kth, axis=-1, kind='introselect', order=None):
+ Perform an indirect partition along the given axis using the
+ algorithm specified by the `kind` keyword. It returns an array of
+ indices of the same shape as `a` that index data along the given
+ axis in partitioned order.
+ Array to sort.
+ Element index to partition by. The k-th element will be in its
+ final sorted position and all smaller elements will be moved
+ before it and all larger elements behind it. The order all
+ elements in the partitions is undefined. If provided with a
+ sequence of k-th it will partition all of them into their sorted
+ position at once.
+ Axis along which to sort. The default is -1 (the last axis). If
+ None, the flattened array is used.
+ Selection algorithm. Default is 'introselect'
+ field can be specified as a string, and not all fields need be
+ index_array : ndarray, int
+ Array of indices that partition `a` along the specified axis.
+ If `a` is one-dimensional, ``a[index_array]`` yields a partitioned `a`.
+ More generally, ``np.take_along_axis(a, index_array, axis=a)`` always
+ yields the partitioned `a`, irrespective of dimensionality.
+ partition : Describes partition algorithms used.
+ ndarray.partition : Inplace partition.
+ argsort : Full indirect sort.
+ take_along_axis : Apply ``index_array`` from argpartition
+ to an array as if by calling partition.
+ See `partition` for notes on the different selection algorithms.
+ One dimensional array:
+ >>> x = np.array([3, 4, 2, 1])
+ >>> x[np.argpartition(x, 3)]
+ >>> x[np.argpartition(x, (1, 3))]
+ >>> x = [3, 4, 2, 1]
+ >>> np.array(x)[np.argpartition(x, 3)]
+ Multi-dimensional array:
+ >>> x = np.array([[3, 4, 2], [1, 3, 1]])
+ >>> index_array = np.argpartition(x, kth=1, axis=-1)
+ >>> np.take_along_axis(x, index_array, axis=-1) # same as np.partition(x, kth=1)
+ array([[2, 3, 4],
+ [1, 1, 3]])
+ return _wrapfunc(a, 'argpartition', kth, axis=axis, kind=kind, order=order)
+def _sort_dispatcher(a, axis=None, kind=None, order=None):
+@array_function_dispatch(_sort_dispatcher)
+def sort(a, axis=-1, kind=None, order=None):
+ Return a sorted copy of an array.
+ and 'mergesort' use timsort or radix sort under the covers and, in general,
+ the actual implementation will vary with data type. The 'mergesort' option
+ sorted_array : ndarray
+ ndarray.sort : Method to sort an array in-place.
+ argsort : Indirect sort.
+ lexsort : Indirect stable sort on multiple keys.
+ searchsorted : Find elements in a sorted array.
+ partition : Partial sort.
+ The various sorting algorithms are characterized by their average speed,
+ worst case performance, work space size, and whether they are stable. A
+ stable sort keeps items with the same key in the same relative
+ order. The four algorithms implemented in NumPy have the following
+ =========== ======= ============= ============ ========
+ 'quicksort' 1 O(n^2) 0 no
+ 'heapsort' 3 O(n*log(n)) 0 no
+ 'mergesort' 2 O(n*log(n)) ~n/2 yes
+ 'timsort' 2 O(n*log(n)) ~n/2 yes
+ .. note:: The datatype determines which of 'mergesort' or 'timsort'
+ is actually used, even if 'mergesort' is specified. User selection
+ at a finer scale is not currently available.
+ All the sort algorithms make temporary copies of the data when
+ sorting along any but the last axis. Consequently, sorting along
+ the last axis is faster and uses less space than sorting along
+ any other axis.
+ The sort order for complex numbers is lexicographic. If both the real
+ and imaginary parts are non-nan then the order is determined by the
+ real parts except when they are equal, in which case the order is
+ determined by the imaginary parts.
+ Previous to numpy 1.4.0 sorting real and complex arrays containing nan
+ values led to undefined behaviour. In numpy versions >= 1.4.0 nan
+ values are sorted to the end. The extended sort order is:
+ * Real: [R, nan]
+ * Complex: [R + Rj, R + nanj, nan + Rj, nan + nanj]
+ where R is a non-nan real value. Complex values with the same nan
+ placements are sorted according to the non-nan part if it exists.
+ Non-nan values are sorted as before.
+ quicksort has been changed to `introsort <https://en.wikipedia.org/wiki/Introsort>`_.
+ When sorting does not make enough progress it switches to
+ `heapsort <https://en.wikipedia.org/wiki/Heapsort>`_.
+ This implementation makes quicksort O(n*log(n)) in the worst case.
+ 'stable' automatically chooses the best stable sorting algorithm
+ for the data type being sorted.
+ It, along with 'mergesort' is currently mapped to
+ `timsort <https://en.wikipedia.org/wiki/Timsort>`_
+ or `radix sort <https://en.wikipedia.org/wiki/Radix_sort>`_
+ depending on the data type.
+ API forward compatibility currently limits the
+ ability to select the implementation and it is hardwired for the different
+ data types.
+ Timsort is added for better performance on already or nearly
+ sorted data. On random data timsort is almost identical to
+ mergesort. It is now used for stable sort while quicksort is still the
+ default sort if none is chosen. For timsort details, refer to
+ `CPython listsort.txt <https://github.com/python/cpython/blob/3.7/Objects/listsort.txt>`_.
+ 'mergesort' and 'stable' are mapped to radix sort for integer data types. Radix sort is an
+ O(n) sort instead of O(n log n).
+ .. versionchanged:: 1.18.0
+ NaT now sorts to the end of arrays for consistency with NaN.
+ >>> a = np.array([[1,4],[3,1]])
+ >>> np.sort(a) # sort along the last axis
+ >>> np.sort(a, axis=None) # sort the flattened array
+ array([1, 1, 3, 4])
+ >>> np.sort(a, axis=0) # sort along the first axis
+ array([[1, 1],
+ >>> dtype = [('name', 'S10'), ('height', float), ('age', int)]
+ >>> values = [('Arthur', 1.8, 41), ('Lancelot', 1.9, 38),
+ ... ('Galahad', 1.7, 38)]
+ >>> a = np.array(values, dtype=dtype) # create a structured array
+ >>> np.sort(a, order='height') # doctest: +SKIP
+ array([('Galahad', 1.7, 38), ('Arthur', 1.8, 41),
+ ('Lancelot', 1.8999999999999999, 38)],
+ dtype=[('name', '|S10'), ('height', '<f8'), ('age', '<i4')])
+ Sort by age, then height if ages are equal:
+ >>> np.sort(a, order=['age', 'height']) # doctest: +SKIP
+ array([('Galahad', 1.7, 38), ('Lancelot', 1.8999999999999999, 38),
+ ('Arthur', 1.8, 41)],
+ a.sort(axis=axis, kind=kind, order=order)
+def _argsort_dispatcher(a, axis=None, kind=None, order=None):
+@array_function_dispatch(_argsort_dispatcher)
+def argsort(a, axis=-1, kind=None, order=None):
+ Returns the indices that would sort an array.
+ Perform an indirect sort along the given axis using the algorithm specified
+ by the `kind` keyword. It returns an array of indices of the same shape as
+ `a` that index data along the given axis in sorted order.
+ Axis along which to sort. The default is -1 (the last axis). If None,
+ the flattened array is used.
+ actual implementation will vary with data type. The 'mergesort' option
+ Array of indices that sort `a` along the specified `axis`.
+ If `a` is one-dimensional, ``a[index_array]`` yields a sorted `a`.
+ More generally, ``np.take_along_axis(a, index_array, axis=axis)``
+ always yields the sorted `a`, irrespective of dimensionality.
+ sort : Describes sorting algorithms used.
+ lexsort : Indirect stable sort with multiple keys.
+ ndarray.sort : Inplace sort.
+ argpartition : Indirect partial sort.
+ take_along_axis : Apply ``index_array`` from argsort
+ to an array as if by calling sort.
+ See `sort` for notes on the different sorting algorithms.
+ As of NumPy 1.4.0 `argsort` works with real/complex arrays containing
+ nan values. The enhanced sort order is documented in `sort`.
+ >>> x = np.array([3, 1, 2])
+ >>> np.argsort(x)
+ array([1, 2, 0])
+ Two-dimensional array:
+ >>> x = np.array([[0, 3], [2, 2]])
+ [2, 2]])
+ >>> ind = np.argsort(x, axis=0) # sorts along first axis (down)
+ >>> ind
+ [1, 0]])
+ >>> np.take_along_axis(x, ind, axis=0) # same as np.sort(x, axis=0)
+ >>> ind = np.argsort(x, axis=1) # sorts along last axis (across)
+ [0, 1]])
+ >>> np.take_along_axis(x, ind, axis=1) # same as np.sort(x, axis=1)
+ Indices of the sorted elements of a N-dimensional array:
+ >>> ind = np.unravel_index(np.argsort(x, axis=None), x.shape)
+ (array([0, 1, 1, 0]), array([0, 0, 1, 1]))
+ >>> x[ind] # same as np.sort(x, axis=None)
+ array([0, 2, 2, 3])
+ Sorting with keys:
+ >>> x = np.array([(1, 0), (0, 1)], dtype=[('x', '<i4'), ('y', '<i4')])
+ array([(1, 0), (0, 1)],
+ >>> np.argsort(x, order=('x','y'))
+ array([1, 0])
+ >>> np.argsort(x, order=('y','x'))
+ array([0, 1])
+ return _wrapfunc(a, 'argsort', axis=axis, kind=kind, order=order)
+def _argmax_dispatcher(a, axis=None, out=None):
+@array_function_dispatch(_argmax_dispatcher)
+def argmax(a, axis=None, out=None):
+ Returns the indices of the maximum values along an axis.
+ By default, the index is into the flattened array, otherwise
+ along the specified axis.
+ be of the appropriate shape and dtype.
+ 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.
+ ndarray.argmax, argmin
+ amax : The maximum value along a given axis.
+ unravel_index : Convert a flat index into an index tuple.
+ take_along_axis : Apply ``np.expand_dims(index_array, axis)``
+ from argmax to an array as if by calling max.
+ In case of multiple occurrences of the maximum values, the indices
+ corresponding to the first occurrence are returned.
+ >>> a = np.arange(6).reshape(2,3) + 10
+ array([[10, 11, 12],
+ [13, 14, 15]])
+ >>> np.argmax(a)
+ >>> np.argmax(a, axis=0)
+ array([1, 1, 1])
+ >>> np.argmax(a, axis=1)
+ array([2, 2])
+ Indexes of the maximal elements of a N-dimensional array:
+ >>> ind = np.unravel_index(np.argmax(a, axis=None), a.shape)
+ (1, 2)
+ >>> a[ind]
+ >>> b = np.arange(6)
+ >>> b[1] = 5
+ array([0, 5, 2, 3, 4, 5])
+ >>> np.argmax(b) # Only the first occurrence is returned.
+ >>> 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)
+ >>> np.take_along_axis(x, np.expand_dims(index_array, axis=-1), axis=-1)
+ array([[4],
+ >>> # Same as np.max(x, axis=-1)
+ >>> np.take_along_axis(x, np.expand_dims(index_array, axis=-1), axis=-1).squeeze(axis=-1)
+ array([4, 3])
+ return _wrapfunc(a, 'argmax', axis=axis, out=out)
+def _argmin_dispatcher(a, axis=None, out=None):
+@array_function_dispatch(_argmin_dispatcher)
+def argmin(a, axis=None, out=None):
+ Returns the indices of the minimum values along an axis.
+ ndarray.argmin, argmax
+ amin : The minimum value along a given axis.
+ from argmin to an array as if by calling min.
+ In case of multiple occurrences of the minimum values, the indices
+ >>> np.argmin(a)
+ >>> np.argmin(a, axis=0)
+ array([0, 0, 0])
+ >>> np.argmin(a, axis=1)
+ Indices of the minimum elements of a N-dimensional array:
+ >>> ind = np.unravel_index(np.argmin(a, axis=None), a.shape)
+ 10
+ >>> b = np.arange(6) + 10
+ >>> b[4] = 10
+ array([10, 11, 12, 13, 10, 15])
+ >>> np.argmin(b) # Only the first occurrence is returned.
+ >>> index_array = np.argmin(x, axis=-1)
+ >>> # Same as np.min(x, axis=-1, keepdims=True)
+ array([[2],
+ [0]])
+ array([2, 0])
+ return _wrapfunc(a, 'argmin', axis=axis, out=out)
+def _searchsorted_dispatcher(a, v, side=None, sorter=None):
+ return (a, v, sorter)
+@array_function_dispatch(_searchsorted_dispatcher)
+def searchsorted(a, v, side='left', sorter=None):
+ Find indices where elements should be inserted to maintain order.
+ Find the indices into a sorted array `a` such that, if the
+ corresponding elements in `v` were inserted before the indices, the
+ order of `a` would be preserved.
+ Assuming that `a` is sorted:
+ ====== ============================
+ `side` returned index `i` satisfies
+ left ``a[i-1] < v <= a[i]``
+ right ``a[i-1] <= v < a[i]``
+ a : 1-D array_like
+ Input array. If `sorter` is None, then it must be sorted in
+ ascending order, otherwise `sorter` must be an array of indices
+ that sort it.
+ Values to insert into `a`.
+ side : {'left', 'right'}, optional
+ If 'left', the index of the first suitable location found is given.
+ If 'right', return the last such index. If there is no suitable
+ index, return either 0 or N (where N is the length of `a`).
+ sorter : 1-D array_like, optional
+ Optional array of integer indices that sort array a into ascending
+ order. They are typically the result of argsort.
+ indices : array of ints
+ Array of insertion points with the same shape as `v`.
+ sort : Return a sorted copy of an array.
+ histogram : Produce histogram from 1-D data.
+ Binary search is used to find the required insertion points.
+ As of NumPy 1.4.0 `searchsorted` works with real/complex arrays containing
+ `nan` values. The enhanced sort order is documented in `sort`.
+ This function uses the same algorithm as the builtin python `bisect.bisect_left`
+ (``side='left'``) and `bisect.bisect_right` (``side='right'``) functions,
+ which is also vectorized in the `v` argument.
+ >>> np.searchsorted([1,2,3,4,5], 3)
+ >>> np.searchsorted([1,2,3,4,5], 3, side='right')
+ >>> np.searchsorted([1,2,3,4,5], [-10, 10, 2, 3])
+ array([0, 5, 1, 2])
+ return _wrapfunc(a, 'searchsorted', v, side=side, sorter=sorter)
+def _resize_dispatcher(a, new_shape):
+@array_function_dispatch(_resize_dispatcher)
+def resize(a, new_shape):
+ Return a new array with the specified shape.
+ If the new array is larger than the original array, then the new
+ array is filled with repeated copies of `a`. Note that this behavior
+ is different from a.resize(new_shape) which fills with zeros instead
+ of repeated copies of `a`.
+ Array to be resized.
+ new_shape : int or tuple of int
+ The new array is formed from the data in the old array, repeated
+ if necessary to fill out the required number of elements. The
+ data are repeated in the order that they are stored in memory.
+ np.reshape : Reshape an array without changing the total size.
+ np.pad : Enlarge and pad an array.
+ np.repeat: Repeat elements of an array.
+ ndarray.resize : resize an array in-place.
+ When the total size of the array does not change `~numpy.reshape` should
+ be used. In most other cases either indexing (to reduce the size)
+ or padding (to increase the size) may be a more appropriate solution.
+ Warning: This functionality does **not** consider axes separately,
+ i.e. it does not apply interpolation/extrapolation.
+ It fills the return array with the required number of elements, taken
+ from `a` as they are laid out in memory, disregarding strides and axes.
+ (This is in case the new shape is smaller. For larger, see above.)
+ This functionality is therefore not suitable to resize images,
+ or data where each axis represents a separate and distinct entity.
+ >>> a=np.array([[0,1],[2,3]])
+ >>> np.resize(a,(2,3))
+ [3, 0, 1]])
+ >>> np.resize(a,(1,4))
+ array([[0, 1, 2, 3]])
+ >>> np.resize(a,(2,4))
+ array([[0, 1, 2, 3],
+ [0, 1, 2, 3]])
+ if isinstance(new_shape, (int, nt.integer)):
+ new_shape = (new_shape,)
+ a = ravel(a)
+ new_size = 1
+ for dim_length in new_shape:
+ new_size *= dim_length
+ if dim_length < 0:
+ raise ValueError('all elements of `new_shape` must be non-negative')
+ if a.size == 0 or new_size == 0:
+ # First case must zero fill. The second would have repeats == 0.
+ return np.zeros_like(a, shape=new_shape)
+ repeats = -(-new_size // a.size) # ceil division
+ a = concatenate((a,) * repeats)[:new_size]
+ return reshape(a, new_shape)
+def _squeeze_dispatcher(a, axis=None):
+@array_function_dispatch(_squeeze_dispatcher)
+def squeeze(a, axis=None):
+ Input data.
+ Selects a subset of the entries of length one in the
+ shape. If an axis is selected with shape entry greater than
+ one, an error is raised.
+ squeezed : ndarray
+ The input array, but with all or a subset of the
+ dimensions of length 1 removed. This is always `a` itself
+ or a view into `a`. Note that if all axes are squeezed,
+ the result is a 0d array and not a scalar.
+ If `axis` is not None, and an axis being squeezed is not of length 1
+ expand_dims : The inverse operation, adding entries of length one
+ reshape : Insert, remove, and combine dimensions, and resize existing ones
+ >>> x = np.array([[[0], [1], [2]]])
+ (1, 3, 1)
+ >>> np.squeeze(x).shape
+ (3,)
+ >>> np.squeeze(x, axis=0).shape
+ (3, 1)
+ >>> np.squeeze(x, axis=1).shape
+ ValueError: cannot select an axis to squeeze out which has size not equal to one
+ >>> np.squeeze(x, axis=2).shape
+ (1, 3)
+ >>> x = np.array([[1234]])
+ (1, 1)
+ >>> np.squeeze(x)
+ array(1234) # 0d array
+ ()
+ >>> np.squeeze(x)[()]
+ 1234
+ squeeze = a.squeeze
+ return _wrapit(a, 'squeeze', axis=axis)
+ return squeeze()
+ return squeeze(axis=axis)
+def _diagonal_dispatcher(a, offset=None, axis1=None, axis2=None):
+@array_function_dispatch(_diagonal_dispatcher)
+def diagonal(a, offset=0, axis1=0, axis2=1):
+ Return specified diagonals.
+ If `a` is 2-D, returns the diagonal of `a` with the given offset,
+ i.e., the collection of elements of the form ``a[i, i+offset]``. If
+ `a` has more than two dimensions, then the axes specified by `axis1`
+ and `axis2` are used to determine the 2-D sub-array whose diagonal is
+ returned. The shape of the resulting array can be determined by
+ removing `axis1` and `axis2` and appending an index to the right equal
+ to the size of the resulting diagonals.
+ In versions of NumPy prior to 1.7, this function always returned a new,
+ independent array containing a copy of the values in the diagonal.
+ In NumPy 1.7 and 1.8, it continues to return a copy of the diagonal,
+ but depending on this fact is deprecated. Writing to the resulting
+ array continues to work as it used to, but a FutureWarning is issued.
+ Starting in NumPy 1.9 it returns a read-only view on the original array.
+ Attempting to write to the resulting array will produce an error.
+ In some future release, it will return a read/write view and writing to
+ the returned array will alter your original array. The returned array
+ will have the same type as the input array.
+ If you don't write to the array returned by this function, then you can
+ just ignore all of the above.
+ If you depend on the current behavior, then we suggest copying the
+ returned array explicitly, i.e., use ``np.diagonal(a).copy()`` instead
+ of just ``np.diagonal(a)``. This will work with both past and future
+ versions of NumPy.
+ Array from which the diagonals are taken.
+ Offset of the diagonal from the main diagonal. Can be positive or
+ negative. Defaults to main diagonal (0).
+ axis1 : int, optional
+ Axis to be used as the first axis of the 2-D sub-arrays from which
+ the diagonals should be taken. Defaults to first axis (0).
+ axis2 : int, optional
+ Axis to be used as the second axis of the 2-D sub-arrays from
+ which the diagonals should be taken. Defaults to second axis (1).
+ array_of_diagonals : ndarray
+ If `a` is 2-D, then a 1-D array containing the diagonal and of the
+ same type as `a` is returned unless `a` is a `matrix`, in which case
+ a 1-D array rather than a (2-D) `matrix` is returned in order to
+ maintain backward compatibility.
+ If ``a.ndim > 2``, then the dimensions specified by `axis1` and `axis2`
+ are removed, and a new axis inserted at the end corresponding to the
+ diagonal.
+ If the dimension of `a` is less than 2.
+ diag : MATLAB work-a-like for 1-D and 2-D arrays.
+ diagflat : Create diagonal arrays.
+ trace : Sum along diagonals.
+ >>> a = np.arange(4).reshape(2,2)
+ >>> a.diagonal()
+ array([0, 3])
+ >>> a.diagonal(1)
+ array([1])
+ A 3-D example:
+ >>> a = np.arange(8).reshape(2,2,2); a
+ >>> a.diagonal(0, # Main diagonals of two arrays created by skipping
+ ... 0, # across the outer(left)-most axis last and
+ ... 1) # the "middle" (row) axis first.
+ array([[0, 6],
+ [1, 7]])
+ The sub-arrays whose main diagonals we just obtained; note that each
+ corresponds to fixing the right-most (column) axis, and that the
+ diagonals are "packed" in rows.
+ >>> a[:,:,0] # main diagonal is [0 6]
+ [4, 6]])
+ >>> a[:,:,1] # main diagonal is [1 7]
+ The anti-diagonal can be obtained by reversing the order of elements
+ using either `numpy.flipud` or `numpy.fliplr`.
+ >>> a = np.arange(9).reshape(3, 3)
+ [3, 4, 5],
+ [6, 7, 8]])
+ >>> np.fliplr(a).diagonal() # Horizontal flip
+ array([2, 4, 6])
+ >>> np.flipud(a).diagonal() # Vertical flip
+ array([6, 4, 2])
+ Note that the order in which the diagonal is retrieved varies depending
+ on the flip function.
+ if isinstance(a, np.matrix):
+ # Make diagonal of matrix 1-D to preserve backward compatibility.
+ return asarray(a).diagonal(offset=offset, axis1=axis1, axis2=axis2)
+ return asanyarray(a).diagonal(offset=offset, axis1=axis1, axis2=axis2)
+def _trace_dispatcher(
+ a, offset=None, axis1=None, axis2=None, dtype=None, out=None):
+@array_function_dispatch(_trace_dispatcher)
+def trace(a, offset=0, axis1=0, axis2=1, dtype=None, out=None):
+ If `a` is 2-D, the sum along its diagonal with the given offset
+ is returned, i.e., the sum of elements ``a[i,i+offset]`` for all i.
+ If `a` has more than two dimensions, then the axes specified by axis1 and
+ axis2 are used to determine the 2-D sub-arrays whose traces are returned.
+ The shape of the resulting array is the same as that of `a` with `axis1`
+ and `axis2` removed.
+ Input array, from which the diagonals are taken.
+ Offset of the diagonal from the main diagonal. Can be both positive
+ and negative. Defaults to 0.
+ axis1, axis2 : int, optional
+ Axes to be used as the first and second axis of the 2-D sub-arrays
+ from which the diagonals should be taken. Defaults are the first two
+ axes of `a`.
+ dtype : dtype, optional
+ Determines the data-type of the returned array and of the accumulator
+ where the elements are summed. If dtype has the value None and `a` is
+ of integer type of precision less than the default integer
+ precision, then the default integer precision is used. Otherwise,
+ the precision is the same as that of `a`.
+ Array into which the output is placed. Its type is preserved and
+ it must be of the right shape to hold the output.
+ sum_along_diagonals : ndarray
+ If `a` is 2-D, the sum along the diagonal is returned. If `a` has
+ larger dimensions, then an array of sums along diagonals is returned.
+ diag, diagonal, diagflat
+ >>> np.trace(np.eye(3))
+ 3.0
+ >>> a = np.arange(8).reshape((2,2,2))
+ array([6, 8])
+ >>> a = np.arange(24).reshape((2,2,2,3))
+ >>> np.trace(a).shape
+ # Get trace of matrix via an array to preserve backward compatibility.
+ return asarray(a).trace(offset=offset, axis1=axis1, axis2=axis2, dtype=dtype, out=out)
+ return asanyarray(a).trace(offset=offset, axis1=axis1, axis2=axis2, dtype=dtype, out=out)
+def _ravel_dispatcher(a, order=None):
+@array_function_dispatch(_ravel_dispatcher)
+def ravel(a, order='C'):
+ """Return a contiguous flattened array.
+ A 1-D array, containing the elements of the input, is returned. A copy is
+ made only if needed.
+ As of NumPy 1.10, the returned array will have the same type as the input
+ array. (for example, a masked array will be returned for a masked array
+ input)
+ Input array. The elements in `a` are read in the order specified by
+ `order`, and packed as a 1-D array.
+ order : {'C','F', 'A', 'K'}, optional
+ The elements of `a` are read using this index order. 'C' means
+ to index the elements in row-major, C-style order,
+ axis index changing slowest. 'F' means to index the elements
+ in column-major, Fortran-style order, with the
+ first index changing fastest, and the last index changing
+ slowest. Note that the 'C' and 'F' options take no account of
+ the memory layout of the underlying array, and only refer to
+ the order of axis indexing. 'A' means to read the elements in
+ Fortran-like index order if `a` is Fortran *contiguous* in
+ memory, C-like order otherwise. 'K' means to read the
+ elements in the order they occur in memory, except for
+ reversing the data when strides are negative. By default, 'C'
+ index order is used.
+ y : array_like
+ y is an array of the same subtype as `a`, with shape ``(a.size,)``.
+ Note that matrices are special cased for backward compatibility, if `a`
+ is a matrix, then y is a 1-D ndarray.
+ ndarray.flat : 1-D iterator over an array.
+ ndarray.flatten : 1-D array copy of the elements of an array
+ in row-major order.
+ ndarray.reshape : Change the shape of an array without changing its data.
+ In row-major, C-style order, in two dimensions, the row index
+ varies the slowest, and the column index the quickest. This can
+ be generalized to multiple dimensions, where row-major order
+ implies that the index along the first axis varies slowest, and
+ the index along the last quickest. The opposite holds for
+ column-major, Fortran-style index ordering.
+ When a view is desired in as many cases as possible, ``arr.reshape(-1)``
+ may be preferable.
+ It is equivalent to ``reshape(-1, order=order)``.
+ >>> x = np.array([[1, 2, 3], [4, 5, 6]])
+ >>> np.ravel(x)
+ >>> x.reshape(-1)
+ >>> np.ravel(x, order='F')
+ When ``order`` is 'A', it will preserve the array's 'C' or 'F' ordering:
+ >>> np.ravel(x.T)
+ >>> np.ravel(x.T, order='A')
+ When ``order`` is 'K', it will preserve orderings that are neither 'C'
+ nor 'F', but won't reverse axes:
+ >>> a = np.arange(3)[::-1]; a
+ array([2, 1, 0])
+ >>> a.ravel(order='C')
+ >>> a.ravel(order='K')
+ >>> a = np.arange(12).reshape(2,3,2).swapaxes(1,2); a
+ array([[[ 0, 2, 4],
+ [ 1, 3, 5]],
+ [[ 6, 8, 10],
+ [ 7, 9, 11]]])
+ array([ 0, 2, 4, 1, 3, 5, 6, 8, 10, 7, 9, 11])
+ array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
+ return asarray(a).ravel(order=order)
+ return asanyarray(a).ravel(order=order)
+def _nonzero_dispatcher(a):
+@array_function_dispatch(_nonzero_dispatcher)
+def nonzero(a):
+ Returns a tuple of arrays, one for each dimension of `a`,
+ containing the indices of the non-zero elements in that
+ dimension. The values in `a` are always tested and returned in
+ row-major, C-style order.
+ To group the indices by element, rather than dimension, use `argwhere`,
+ which returns a row for each non-zero element.
+ When called on a zero-d array or scalar, ``nonzero(a)`` is treated
+ as ``nonzero(atleast_1d(a))``.
+ .. deprecated:: 1.17.0
+ Use `atleast_1d` explicitly if this behavior is deliberate.
+ tuple_of_arrays : tuple
+ Indices of elements that are non-zero.
+ flatnonzero :
+ Return indices that are non-zero in the flattened version of the input
+ ndarray.nonzero :
+ Equivalent ndarray method.
+ count_nonzero :
+ Counts the number of non-zero elements in the input array.
+ While the nonzero values can be obtained with ``a[nonzero(a)]``, it is
+ recommended to use ``x[x.astype(bool)]`` or ``x[x != 0]`` instead, which
+ will correctly handle 0-d arrays.
+ >>> x = np.array([[3, 0, 0], [0, 4, 0], [5, 6, 0]])
+ array([[3, 0, 0],
+ [0, 4, 0],
+ [5, 6, 0]])
+ >>> np.nonzero(x)
+ (array([0, 1, 2, 2]), array([0, 1, 0, 1]))
+ >>> x[np.nonzero(x)]
+ >>> np.transpose(np.nonzero(x))
+ array([[0, 0],
+ [1, 1],
+ [2, 0],
+ [2, 1]])
+ A common use for ``nonzero`` is to find the indices of an array, where
+ a condition is True. Given an array `a`, the condition `a` > 3 is a
+ boolean array and since False is interpreted as 0, np.nonzero(a > 3)
+ yields the indices of the `a` where the condition is true.
+ >>> a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
+ >>> a > 3
+ array([[False, False, False],
+ [ True, True, True],
+ [ True, True, True]])
+ >>> np.nonzero(a > 3)
+ (array([1, 1, 1, 2, 2, 2]), array([0, 1, 2, 0, 1, 2]))
+ Using this result to index `a` is equivalent to using the mask directly:
+ >>> a[np.nonzero(a > 3)]
+ array([4, 5, 6, 7, 8, 9])
+ >>> a[a > 3] # prefer this spelling
+ ``nonzero`` can also be called as a method of the array.
+ >>> (a > 3).nonzero()
+ return _wrapfunc(a, 'nonzero')
+def _shape_dispatcher(a):
+@array_function_dispatch(_shape_dispatcher)
+def shape(a):
+ Return the shape of an array.
+ The elements of the shape tuple give the lengths of the
+ corresponding array dimensions.
+ len
+ ndarray.shape : Equivalent array method.
+ >>> np.shape(np.eye(3))
+ >>> np.shape([[1, 2]])
+ >>> np.shape([0])
+ >>> np.shape(0)
+ >>> a = np.array([(1, 2), (3, 4)], dtype=[('x', 'i4'), ('y', 'i4')])
+ >>> np.shape(a)
+ >>> a.shape
+ result = a.shape
+ result = asarray(a).shape
+def _compress_dispatcher(condition, a, axis=None, out=None):
+ return (condition, a, out)
+@array_function_dispatch(_compress_dispatcher)
+def compress(condition, a, axis=None, out=None):
+ Return selected slices of an array along given axis.
+ When working along a given axis, a slice along that axis is returned in
+ `output` for each index where `condition` evaluates to True. When
+ working on a 1-D array, `compress` is equivalent to `extract`.
+ condition : 1-D array of bools
+ Array that selects which entries to return. If len(condition)
+ is less than the size of `a` along the given axis, then output is
+ truncated to the length of the condition array.
+ Array from which to extract a part.
+ Axis along which to take slices. If None (default), work on the
+ flattened array.
+ Output array. Its type is preserved and it must be of the right
+ shape to hold the output.
+ compressed_array : ndarray
+ A copy of `a` without the slices along axis for which `condition`
+ is false.
+ take, choose, diag, diagonal, select
+ ndarray.compress : Equivalent method in ndarray
+ extract: Equivalent method when working on 1-D arrays
+ :ref:`ufuncs-output-type`
+ >>> a = np.array([[1, 2], [3, 4], [5, 6]])
+ >>> np.compress([0, 1], a, axis=0)
+ array([[3, 4]])
+ >>> np.compress([False, True, True], a, axis=0)
+ array([[3, 4],
+ >>> np.compress([False, True], a, axis=1)
+ [4],
+ [6]])
+ Working on the flattened array does not return slices along an axis but
+ selects elements.
+ >>> np.compress([False, True], a)
+ array([2])
+ return _wrapfunc(a, 'compress', condition, axis=axis, out=out)
+def _clip_dispatcher(a, a_min, a_max, out=None, **kwargs):
+ return (a, a_min, a_max)
+@array_function_dispatch(_clip_dispatcher)
+def clip(a, a_min, a_max, out=None, **kwargs):
+ Clip (limit) the values in an array.
+ Given an interval, values outside the interval are clipped to
+ the interval edges. For example, if an interval of ``[0, 1]``
+ is specified, values smaller than 0 become 0, and values larger
+ than 1 become 1.
+ Equivalent to but faster than ``np.minimum(a_max, np.maximum(a, a_min))``.
+ No check is performed to ensure ``a_min < a_max``.
+ Array containing elements to clip.
+ a_min, a_max : array_like or None
+ Minimum and maximum value. If ``None``, clipping is not performed on
+ the corresponding edge. Only one of `a_min` and `a_max` may be
+ ``None``. Both are broadcast against `a`.
+ The results will be placed in this array. It may be the input
+ array for in-place clipping. `out` must be of the right shape
+ to hold the output. Its type is preserved.
+ For other keyword-only arguments, see the
+ :ref:`ufunc docs <ufuncs.kwargs>`.
+ clipped_array : ndarray
+ An array with the elements of `a`, but where values
+ < `a_min` are replaced with `a_min`, and those > `a_max`
+ with `a_max`.
+ >>> np.clip(a, 1, 8)
+ array([1, 1, 2, 3, 4, 5, 6, 7, 8, 8])
+ >>> np.clip(a, 3, 6, out=a)
+ array([3, 3, 3, 3, 4, 5, 6, 6, 6, 6])
+ >>> np.clip(a, [3, 4, 1, 1, 1, 4, 4, 4, 4, 4], 8)
+ array([3, 4, 2, 3, 4, 5, 6, 7, 8, 8])
+ return _wrapfunc(a, 'clip', a_min, a_max, out=out, **kwargs)
+def _sum_dispatcher(a, axis=None, dtype=None, out=None, keepdims=None,
+ initial=None, where=None):
+@array_function_dispatch(_sum_dispatcher)
+def sum(a, axis=None, dtype=None, out=None, keepdims=np._NoValue,
+ initial=np._NoValue, where=np._NoValue):
+ Sum of array elements over a given axis.
+ Elements to sum.
+ Axis or axes along which a sum is performed. The default,
+ axis=None, will sum all of the elements of the input array. If
+ axis is negative it counts from the last to the first axis.
+ If axis is a tuple of ints, a sum is performed on all of the axes
+ specified in the tuple instead of a single axis or all the axes as
+ before.
+ The type of the returned array and of the accumulator in which the
+ elements are summed. The dtype of `a` is used by default unless `a`
+ has an integer dtype of less precision than the default platform
+ integer. In that case, if `a` is signed then the platform integer
+ is used while if `a` is unsigned then an unsigned integer of the
+ same precision as the platform integer is used.
+ Alternative output array in which to place the result. It must have
+ the same shape as the expected output, but the type of the output
+ values will be cast if necessary.
+ the result will broadcast correctly against the input array.
+ If the default value is passed, then `keepdims` will not be
+ passed through to the `sum` method of sub-classes of
+ `ndarray`, however any non-default value will be. If the
+ sub-class' method does not implement `keepdims` any
+ exceptions will be raised.
+ Starting value for the sum. See `~numpy.ufunc.reduce` for details.
+ Elements to include in the sum. See `~numpy.ufunc.reduce` for details.
+ sum_along_axis : ndarray
+ An array with the same shape as `a`, with the specified
+ axis removed. If `a` is a 0-d array, or if `axis` is None, a scalar
+ is returned. If an output array is specified, a reference to
+ `out` is returned.
+ ndarray.sum : Equivalent method.
+ add.reduce : Equivalent functionality of `add`.
+ cumsum : Cumulative sum of array elements.
+ trapz : Integration of array values using the composite trapezoidal rule.
+ mean, average
+ Arithmetic is modular when using integer types, and no error is
+ raised on overflow.
+ The sum of an empty array is the neutral element 0:
+ >>> np.sum([])
+ 0.0
+ For floating point numbers the numerical precision of sum (and
+ ``np.add.reduce``) is in general limited by directly adding each number
+ individually to the result causing rounding errors in every step.
+ However, often numpy will use a numerically better approach (partial
+ pairwise summation) leading to improved precision in many use-cases.
+ This improved precision is always provided when no ``axis`` is given.
+ When ``axis`` is given, it will depend on which axis is summed.
+ Technically, to provide the best speed possible, the improved precision
+ is only used when the summation is along the fast axis in memory.
+ Note that the exact precision may vary depending on other parameters.
+ In contrast to NumPy, Python's ``math.fsum`` function uses a slower but
+ more precise approach to summation.
+ Especially when summing a large number of lower precision floating point
+ numbers, such as ``float32``, numerical errors can become significant.
+ In such cases it can be advisable to use `dtype="float64"` to use a higher
+ precision for the output.
+ >>> np.sum([0.5, 1.5])
+ 2.0
+ >>> np.sum([0.5, 0.7, 0.2, 1.5], dtype=np.int32)
+ >>> np.sum([[0, 1], [0, 5]])
+ 6
+ >>> np.sum([[0, 1], [0, 5]], axis=0)
+ array([0, 6])
+ >>> np.sum([[0, 1], [0, 5]], axis=1)
+ array([1, 5])
+ >>> np.sum([[0, 1], [np.nan, 5]], where=[False, True], axis=1)
+ array([1., 5.])
+ If the accumulator is too small, overflow occurs:
+ >>> np.ones(128, dtype=np.int8).sum(dtype=np.int8)
+ -128
+ You can also start the sum with a value other than zero:
+ >>> np.sum([10], initial=5)
+ if isinstance(a, _gentype):
+ # 2018-02-25, 1.15.0
+ "Calling np.sum(generator) is deprecated, and in the future will give a different result. "
+ "Use np.sum(np.fromiter(generator)) or the python sum builtin instead.",
+ res = _sum_(a)
+ if out is not None:
+ out[...] = res
+ return _wrapreduction(a, np.add, 'sum', axis, dtype, out, keepdims=keepdims,
+ initial=initial, where=where)
+def _any_dispatcher(a, axis=None, out=None, keepdims=None, *,
+ where=np._NoValue):
+ return (a, where, out)
+@array_function_dispatch(_any_dispatcher)
+def any(a, axis=None, out=None, keepdims=np._NoValue, *, where=np._NoValue):
+ Test whether any array element along a given axis evaluates to True.
+ Returns single boolean unless `axis` is not ``None``
+ Input array or object that can be converted to an array.
+ Axis or axes along which a logical OR reduction is performed.
+ The default (``axis=None``) is to perform a logical OR over all
+ the dimensions of the input array. `axis` may be negative, in
+ Alternate output array in which to place the result. It must have
+ the same shape as the expected output and its type is preserved
+ (e.g., if it is of type float, then it will remain so, returning
+ 1.0 for True and 0.0 for False, regardless of the type of `a`).
+ See :ref:`ufuncs-output-type` for more details.
+ passed through to the `any` method of sub-classes of
+ Elements to include in checking for any `True` values.
+ See `~numpy.ufunc.reduce` for details.
+ any : bool or ndarray
+ A new boolean or `ndarray` is returned unless `out` is specified,
+ in which case a reference to `out` is returned.
+ ndarray.any : equivalent method
+ all : Test whether all elements along a given axis evaluate to True.
+ Not a Number (NaN), positive infinity and negative infinity evaluate
+ to `True` because these are not equal to zero.
+ >>> np.any([[True, False], [True, True]])
+ >>> np.any([[True, False], [False, False]], axis=0)
+ array([ True, False])
+ >>> np.any([-1, 0, 5])
+ >>> np.any(np.nan)
+ >>> np.any([[True, False], [False, False]], where=[[False], [True]])
+ >>> o=np.array(False)
+ >>> z=np.any([-1, 4, 5], out=o)
+ >>> z, o
+ (array(True), array(True))
+ >>> # Check now that z is a reference to o
+ >>> z is o
+ >>> id(z), id(o) # identity of z and o # doctest: +SKIP
+ (191614240, 191614240)
+ return _wrapreduction(a, np.logical_or, 'any', axis, None, out,
+def _all_dispatcher(a, axis=None, out=None, keepdims=None, *,
+ where=None):
+@array_function_dispatch(_all_dispatcher)
+def all(a, axis=None, out=None, keepdims=np._NoValue, *, where=np._NoValue):
+ Test whether all array elements along a given axis evaluate to True.
+ Axis or axes along which a logical AND reduction is performed.
+ The default (``axis=None``) is to perform a logical AND over all
+ Alternate output array in which to place the result.
+ It must have the same shape as the expected output and its
+ type is preserved (e.g., if ``dtype(out)`` is float, the result
+ will consist of 0.0's and 1.0's). See :ref:`ufuncs-output-type` for more
+ details.
+ passed through to the `all` method of sub-classes of
+ Elements to include in checking for all `True` values.
+ all : ndarray, bool
+ A new boolean or array is returned unless `out` is specified,
+ ndarray.all : equivalent method
+ any : Test whether any element along a given axis evaluates to True.
+ Not a Number (NaN), positive infinity and negative infinity
+ evaluate to `True` because these are not equal to zero.
+ >>> np.all([[True,False],[True,True]])
+ >>> np.all([[True,False],[True,True]], axis=0)
+ >>> np.all([-1, 4, 5])
+ >>> np.all([1.0, np.nan])
+ >>> np.all([[True, True], [False, True]], where=[[True], [False]])
+ >>> z=np.all([-1, 4, 5], out=o)
+ >>> id(z), id(o), z
+ (28293632, 28293632, array(True)) # may vary
+ return _wrapreduction(a, np.logical_and, 'all', axis, None, out,
+def _cumsum_dispatcher(a, axis=None, dtype=None, out=None):
+@array_function_dispatch(_cumsum_dispatcher)
+def cumsum(a, axis=None, dtype=None, out=None):
+ Return the cumulative sum of the elements along a given axis.
+ Axis along which the cumulative sum is computed. The default
+ (None) is to compute the cumsum over the flattened array.
+ Type of the returned array and of the accumulator in which the
+ elements are summed. If `dtype` is not specified, it defaults
+ to the dtype of `a`, unless `a` has an integer dtype with a
+ precision less than that of the default platform integer. In
+ that case, the default platform integer is used.
+ 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. See :ref:`ufuncs-output-type` for
+ more details.
+ cumsum_along_axis : ndarray.
+ A new array holding the result is returned unless `out` is
+ specified, in which case a reference to `out` is returned. The
+ 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.
+ sum : Sum array elements.
+ diff : Calculate the n-th discrete difference along given axis.
+ >>> np.cumsum(a)
+ array([ 1, 3, 6, 10, 15, 21])
+ >>> np.cumsum(a, dtype=float) # specifies type of output value(s)
+ array([ 1., 3., 6., 10., 15., 21.])
+ >>> np.cumsum(a,axis=0) # sum over rows for each of the 3 columns
+ [5, 7, 9]])
+ >>> np.cumsum(a,axis=1) # sum over columns for each of the 2 rows
+ array([[ 1, 3, 6],
+ [ 4, 9, 15]])
+ return _wrapfunc(a, 'cumsum', axis=axis, dtype=dtype, out=out)
+def _ptp_dispatcher(a, axis=None, out=None, keepdims=None):
+@array_function_dispatch(_ptp_dispatcher)
+def ptp(a, axis=None, out=None, keepdims=np._NoValue):
+ Range of values (maximum - minimum) along an axis.
+ The name of the function comes from the acronym for 'peak to peak'.
+ `ptp` preserves the data type of the array. This means the
+ return value for an input of signed integers with n bits
+ (e.g. `np.int8`, `np.int16`, etc) is also a signed integer
+ with n bits. In that case, peak-to-peak values greater than
+ ``2**(n-1)-1`` will be returned as negative values. An example
+ with a work-around is shown below.
+ Input values.
+ Axis along which to find the peaks. By default, flatten the
+ array. `axis` may be negative, in
+ out : array_like
+ have the same shape and buffer length as the expected output,
+ but the type of the output values will be cast if necessary.
+ passed through to the `ptp` method of sub-classes of
+ ptp : ndarray
+ A new array holding the result, unless `out` was
+ specified, in which case a reference to `out` is returned.
+ >>> x = np.array([[4, 9, 2, 10],
+ ... [6, 9, 7, 12]])
+ >>> np.ptp(x, axis=1)
+ array([8, 6])
+ >>> np.ptp(x, axis=0)
+ array([2, 0, 5, 2])
+ >>> np.ptp(x)
+ This example shows that a negative value can be returned when
+ the input is an array of signed integers.
+ >>> y = np.array([[1, 127],
+ ... [0, 127],
+ ... [-1, 127],
+ ... [-2, 127]], dtype=np.int8)
+ >>> np.ptp(y, axis=1)
+ array([ 126, 127, -128, -127], dtype=int8)
+ A work-around is to use the `view()` method to view the result as
+ unsigned integers with the same bit width:
+ >>> np.ptp(y, axis=1).view(np.uint8)
+ array([126, 127, 128, 129], dtype=uint8)
+ kwargs = {}
+ if keepdims is not np._NoValue:
+ kwargs['keepdims'] = keepdims
+ if type(a) is not mu.ndarray:
+ ptp = a.ptp
+ return ptp(axis=axis, out=out, **kwargs)
+ return _methods._ptp(a, axis=axis, out=out, **kwargs)
+def _amax_dispatcher(a, axis=None, out=None, keepdims=None, initial=None,
+@array_function_dispatch(_amax_dispatcher)
+def amax(a, axis=None, out=None, keepdims=np._NoValue, initial=np._NoValue,
+ Return the maximum of an array or maximum along an axis.
+ Axis or axes along which to operate. By default, flattened input is
+ used.
+ If this is a tuple of ints, the maximum is selected over multiple axes,
+ instead of a single axis or all the axes as before.
+ Alternative output array in which to place the result. Must
+ be of the same shape and buffer length as the expected output.
+ passed through to the `amax` method of sub-classes of
+ The minimum value of an output element. Must be present to allow
+ computation on empty slice. See `~numpy.ufunc.reduce` for details.
+ Elements to compare for the maximum. See `~numpy.ufunc.reduce`
+ for details.
+ amax : ndarray or scalar
+ Maximum of `a`. If `axis` is None, the result is a scalar value.
+ If `axis` is given, the result is an array of dimension
+ ``a.ndim - 1``.
+ amin :
+ The minimum value of an array along a given axis, propagating any NaNs.
+ nanmax :
+ The maximum value of an array along a given axis, ignoring any NaNs.
+ maximum :
+ Element-wise maximum of two arrays, propagating any NaNs.
+ fmax :
+ Element-wise maximum of two arrays, ignoring any NaNs.
+ argmax :
+ Return the indices of the maximum values.
+ nanmin, minimum, fmin
+ NaN values are propagated, that is if at least one item is NaN, the
+ corresponding max value will be NaN as well. To ignore NaN values
+ (MATLAB behavior), please use nanmax.
+ Don't use `amax` for element-wise comparison of 2 arrays; when
+ ``a.shape[0]`` is 2, ``maximum(a[0], a[1])`` is faster than
+ ``amax(a, axis=0)``.
+ >>> a = np.arange(4).reshape((2,2))
+ >>> np.amax(a) # Maximum of the flattened array
+ >>> np.amax(a, axis=0) # Maxima along the first axis
+ >>> np.amax(a, axis=1) # Maxima along the second axis
+ >>> np.amax(a, where=[False, True], initial=-1, axis=0)
+ array([-1, 3])
+ >>> b = np.arange(5, dtype=float)
+ >>> b[2] = np.NaN
+ >>> np.amax(b)
+ >>> np.amax(b, where=~np.isnan(b), initial=-1)
+ 4.0
+ >>> np.nanmax(b)
+ 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)
+ 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)
+ >>> max([5], default=6)
+ return _wrapreduction(a, np.maximum, 'max', axis, None, out,
+ keepdims=keepdims, initial=initial, where=where)
+def _amin_dispatcher(a, axis=None, out=None, keepdims=None, initial=None,
+@array_function_dispatch(_amin_dispatcher)
+def amin(a, axis=None, out=None, keepdims=np._NoValue, initial=np._NoValue,
+ Return the minimum of an array or minimum along an axis.
+ If this is a tuple of ints, the minimum is selected over multiple axes,
+ passed through to the `amin` method of sub-classes of
+ The maximum value of an output element. Must be present to allow
+ Elements to compare for the minimum. See `~numpy.ufunc.reduce`
+ amin : ndarray or scalar
+ Minimum of `a`. If `axis` is None, the result is a scalar value.
+ amax :
+ The maximum value of an array along a given axis, propagating any NaNs.
+ nanmin :
+ The minimum value of an array along a given axis, ignoring any NaNs.
+ minimum :
+ Element-wise minimum of two arrays, propagating any NaNs.
+ fmin :
+ Element-wise minimum of two arrays, ignoring any NaNs.
+ argmin :
+ Return the indices of the minimum values.
+ nanmax, maximum, fmax
+ corresponding min value will be NaN as well. To ignore NaN values
+ (MATLAB behavior), please use nanmin.
+ Don't use `amin` for element-wise comparison of 2 arrays; when
+ ``a.shape[0]`` is 2, ``minimum(a[0], a[1])`` is faster than
+ ``amin(a, axis=0)``.
+ >>> np.amin(a) # Minimum of the flattened array
+ >>> np.amin(a, axis=0) # Minima along the first axis
+ >>> np.amin(a, axis=1) # Minima along the second axis
+ array([0, 2])
+ >>> np.amin(a, where=[False, True], initial=10, axis=0)
+ array([10, 1])
+ >>> np.amin(b)
+ >>> np.amin(b, where=~np.isnan(b), initial=10)
+ >>> np.nanmin(b)
+ >>> np.min([[-50], [10]], axis=-1, initial=0)
+ array([-50, 0])
+ minimum is determined, unlike for the default argument Python's max
+ Notice that this isn't the same as Python's ``default`` argument.
+ >>> np.min([6], initial=5)
+ >>> min([6], default=5)
+ return _wrapreduction(a, np.minimum, 'min', axis, None, out,
+def _alen_dispathcer(a):
+@array_function_dispatch(_alen_dispathcer)
+def alen(a):
+ Return the length of the first dimension of the input array.
+ .. deprecated:: 1.18
+ `numpy.alen` is deprecated, use `len` instead.
+ alen : int
+ Length of the first dimension of `a`.
+ shape, size
+ >>> a = np.zeros((7,4,5))
+ >>> a.shape[0]
+ >>> np.alen(a)
+ # NumPy 1.18.0, 2019-08-02
+ "`np.alen` is deprecated, use `len` instead",
+ DeprecationWarning, stacklevel=2)
+ return len(a)
+ return len(array(a, ndmin=1))
+def _prod_dispatcher(a, axis=None, dtype=None, out=None, keepdims=None,
+@array_function_dispatch(_prod_dispatcher)
+def prod(a, axis=None, dtype=None, out=None, keepdims=np._NoValue,
+ Return the product of array elements over a given axis.
+ Axis or axes along which a product is performed. The default,
+ axis=None, will calculate the product of all the elements in the
+ input array. If axis is negative it counts from the last to the
+ first axis.
+ If axis is a tuple of ints, a product is performed on all of the
+ axes specified in the tuple instead of a single axis or all the
+ axes as before.
+ The type of the returned array, as well as of the accumulator in
+ which the elements are multiplied. The dtype of `a` is used by
+ default unless `a` has an integer dtype of less precision than the
+ default platform integer. In that case, if `a` is signed then the
+ platform integer is used while if `a` is unsigned then an unsigned
+ integer of the same precision as the platform integer is used.
+ 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 input array.
+ passed through to the `prod` method of sub-classes of
+ The starting value for this product. See `~numpy.ufunc.reduce` for details.
+ Elements to include in the product. See `~numpy.ufunc.reduce` for details.
+ product_along_axis : ndarray, see `dtype` parameter above.
+ An array shaped as `a` but with the specified axis removed.
+ Returns a reference to `out` if specified.
+ ndarray.prod : equivalent method
+ raised on overflow. That means that, on a 32-bit platform:
+ >>> x = np.array([536870910, 536870910, 536870910, 536870910])
+ >>> np.prod(x)
+ 16 # may vary
+ The product of an empty array is the neutral element 1:
+ >>> np.prod([])
+ 1.0
+ By default, calculate the product of all elements:
+ >>> np.prod([1.,2.])
+ Even when the input array is two-dimensional:
+ >>> np.prod([[1.,2.],[3.,4.]])
+ 24.0
+ But we can also specify the axis over which to multiply:
+ >>> np.prod([[1.,2.],[3.,4.]], axis=1)
+ array([ 2., 12.])
+ Or select specific elements to include:
+ >>> np.prod([1., np.nan, 3.], where=[True, False, True])
+ If the type of `x` is unsigned, then the output type is
+ the unsigned platform integer:
+ >>> x = np.array([1, 2, 3], dtype=np.uint8)
+ >>> np.prod(x).dtype == np.uint
+ If `x` is of a signed integer type, then the output type
+ is the default platform integer:
+ >>> x = np.array([1, 2, 3], dtype=np.int8)
+ >>> np.prod(x).dtype == int
+ You can also start the product with a value other than one:
+ >>> np.prod([1, 2], initial=5)
+ return _wrapreduction(a, np.multiply, 'prod', axis, dtype, out,
+def _cumprod_dispatcher(a, axis=None, dtype=None, out=None):
+@array_function_dispatch(_cumprod_dispatcher)
+def cumprod(a, axis=None, dtype=None, out=None):
+ Return the cumulative product of elements along a given axis.
+ Axis along which the cumulative product is computed. By default
+ the input is flattened.
+ Type of the returned array, as well as of the accumulator in which
+ the elements are multiplied. If *dtype* is not specified, it
+ defaults to the dtype of `a`, unless `a` has an integer dtype with
+ a precision less than that of the default platform integer. In
+ that case, the default platform integer is used instead.
+ but the type of the resulting values will be cast if necessary.
+ cumprod : ndarray
+ specified, in which case a reference to out is returned.
+ >>> a = np.array([1,2,3])
+ >>> np.cumprod(a) # intermediate results 1, 1*2
+ ... # total product 1*2*3 = 6
+ array([1, 2, 6])
+ >>> a = np.array([[1, 2, 3], [4, 5, 6]])
+ >>> np.cumprod(a, dtype=float) # specify type of output
+ array([ 1., 2., 6., 24., 120., 720.])
+ The cumulative product for each column (i.e., over the rows) of `a`:
+ >>> np.cumprod(a, axis=0)
+ array([[ 1, 2, 3],
+ [ 4, 10, 18]])
+ The cumulative product for each row (i.e. over the columns) of `a`:
+ >>> np.cumprod(a,axis=1)
+ array([[ 1, 2, 6],
+ [ 4, 20, 120]])
+ return _wrapfunc(a, 'cumprod', axis=axis, dtype=dtype, out=out)
+def _ndim_dispatcher(a):
+@array_function_dispatch(_ndim_dispatcher)
+def ndim(a):
+ Return the number of dimensions of an array.
+ Input array. If it is not already an ndarray, a conversion is
+ attempted.
+ number_of_dimensions : int
+ The number of dimensions in `a`. Scalars are zero-dimensional.
+ ndarray.ndim : equivalent method
+ shape : dimensions of array
+ ndarray.shape : dimensions of array
+ >>> np.ndim([[1,2,3],[4,5,6]])
+ >>> np.ndim(np.array([[1,2,3],[4,5,6]]))
+ >>> np.ndim(1)
+ return a.ndim
+ return asarray(a).ndim
+def _size_dispatcher(a, axis=None):
+@array_function_dispatch(_size_dispatcher)
+def size(a, axis=None):
+ Return the number of elements along a given axis.
+ Axis along which the elements are counted. By default, give
+ the total number of elements.
+ element_count : int
+ Number of elements along the specified axis.
+ ndarray.size : number of elements in array
+ >>> a = np.array([[1,2,3],[4,5,6]])
+ >>> np.size(a)
+ >>> np.size(a,1)
+ >>> np.size(a,0)
+ return a.size
+ return asarray(a).size
+ return a.shape[axis]
+ return asarray(a).shape[axis]
+def _around_dispatcher(a, decimals=None, out=None):
+@array_function_dispatch(_around_dispatcher)
+def around(a, decimals=0, out=None):
+ Evenly round to the given number of decimals.
+ decimals : int, optional
+ Number of decimal places to round to (default: 0). If
+ decimals is negative, it specifies the number of positions to
+ the left of the decimal point.
+ values will be cast if necessary. See :ref:`ufuncs-output-type` for more
+ rounded_array : ndarray
+ An array of the same type as `a`, containing the rounded values.
+ Unless `out` was specified, a new array is created. A reference to
+ the result is returned.
+ The real and imaginary parts of complex numbers are rounded
+ separately. The result of rounding a float is a float.
+ ndarray.round : equivalent method
+ ceil, fix, floor, rint, trunc
+ 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.
+ ``np.around`` uses a fast but sometimes inexact algorithm to round
+ floating-point datatypes. For positive `decimals` it is equivalent to
+ ``np.true_divide(np.rint(a * 10**decimals), 10**decimals)``, which has
+ error due to the inexact representation of decimal fractions in the IEEE
+ floating point standard [1]_ and errors introduced when scaling by powers
+ of ten. For instance, note the extra "1" in the following:
+ >>> np.round(56294995342131.5, 3)
+ 56294995342131.51
+ If your goal is to print such values with a fixed number of decimals, it is
+ preferable to use numpy's float printing routines to limit the number of
+ printed decimals:
+ >>> np.format_float_positional(56294995342131.5, precision=3)
+ '56294995342131.5'
+ The float printing routines use an accurate but much more computationally
+ demanding algorithm to compute the number of digits after the decimal
+ point.
+ Alternatively, Python's builtin `round` function uses a more accurate
+ but slower algorithm for 64-bit floating point values:
+ >>> round(56294995342131.5, 3)
+ 56294995342131.5
+ >>> np.round(16.055, 2), round(16.055, 2) # equals 16.0549999999999997
+ (16.06, 16.05)
+ References
+ .. [1] "Lecture Notes on the Status of IEEE 754", William Kahan,
+ https://people.eecs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF
+ .. [2] "How Futile are Mindless Assessments of
+ Roundoff in Floating-Point Computation?", William Kahan,
+ https://people.eecs.berkeley.edu/~wkahan/Mindless.pdf
+ >>> np.around([0.37, 1.64])
+ array([0., 2.])
+ >>> np.around([0.37, 1.64], decimals=1)
+ array([0.4, 1.6])
+ >>> np.around([.5, 1.5, 2.5, 3.5, 4.5]) # rounds to nearest even value
+ array([0., 2., 2., 4., 4.])
+ >>> np.around([1,2,3,11], decimals=1) # ndarray of ints is returned
+ array([ 1, 2, 3, 11])
+ >>> np.around([1,2,3,11], decimals=-1)
+ array([ 0, 0, 0, 10])
+ return _wrapfunc(a, 'round', decimals=decimals, out=out)
+def _mean_dispatcher(a, axis=None, dtype=None, out=None, keepdims=None, *,
+@array_function_dispatch(_mean_dispatcher)
+def mean(a, axis=None, dtype=None, out=None, keepdims=np._NoValue, *,
+ Compute the arithmetic mean along the specified axis.
+ Returns the average of the array elements. The average is taken over
+ the flattened array by default, otherwise over the specified axis.
+ `float64` intermediate and return values are used for integer inputs.
+ Array containing numbers whose mean is desired. If `a` is not an
+ array, a conversion is attempted.
+ Axis or axes along which the means are computed. The default is to
+ compute the mean of the flattened array.
+ If this is a tuple of ints, a mean is performed over multiple axes,
+ Type to use in computing the mean. For integer inputs, the default
+ is `float64`; for floating point inputs, it is the same as the
+ input dtype.
+ Alternate output array in which to place the result. The default
+ is ``None``; if provided, it must have the same shape as the
+ expected output, but the type will be cast if necessary.
+ passed through to the `mean` method of sub-classes of
+ Elements to include in the mean. See `~numpy.ufunc.reduce` for details.
+ m : ndarray, see dtype parameter above
+ If `out=None`, returns a new array containing the mean values,
+ otherwise a reference to the output array is returned.
+ average : Weighted average
+ std, var, nanmean, nanstd, nanvar
+ The arithmetic mean is the sum of the elements along the axis divided
+ by the number of elements.
+ Note that for floating-point input, the mean is computed using the
+ same precision the input has. Depending on the input data, this can
+ cause the results to be inaccurate, especially for `float32` (see
+ example below). Specifying a higher-precision accumulator using the
+ `dtype` keyword can alleviate this issue.
+ By default, `float16` results are computed using `float32` intermediates
+ for extra precision.
+ >>> np.mean(a)
+ 2.5
+ >>> np.mean(a, axis=0)
+ >>> np.mean(a, axis=1)
+ array([1.5, 3.5])
+ In single precision, `mean` can be inaccurate:
+ >>> a = np.zeros((2, 512*512), dtype=np.float32)
+ >>> a[0, :] = 1.0
+ >>> a[1, :] = 0.1
+ 0.54999924
+ Computing the mean in float64 is more accurate:
+ >>> np.mean(a, dtype=np.float64)
+ 0.55000000074505806 # may vary
+ Specifying a where argument:
+ >>> a = np.array([[5, 9, 13], [14, 10, 12], [11, 15, 19]])
+ 12.0
+ >>> np.mean(a, where=[[True], [False], [False]])
+ 9.0
+ if where is not np._NoValue:
+ kwargs['where'] = where
+ mean = a.mean
+ return mean(axis=axis, dtype=dtype, out=out, **kwargs)
+ return _methods._mean(a, axis=axis, dtype=dtype,
+ out=out, **kwargs)
+def _std_dispatcher(a, axis=None, dtype=None, out=None, ddof=None,
+ keepdims=None, *, where=None):
+@array_function_dispatch(_std_dispatcher)
+def std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=np._NoValue, *,
+ Compute the standard deviation along the specified axis.
+ Returns the standard deviation, a measure of the spread of a distribution,
+ of the array elements. The standard deviation is computed for the
+ flattened array by default, otherwise over the specified axis.
+ Calculate the standard deviation of these values.
+ Axis or axes along which the standard deviation is computed. The
+ default is to compute the standard deviation of the flattened array.
+ If this is a tuple of ints, a standard deviation is performed over
+ multiple axes, instead of a single axis or all the axes as before.
+ Type to use in computing the standard deviation. For arrays of
+ integer type the default is float64, for arrays of float types it is
+ the same as the array type.
+ the same shape as the expected output but the type (of the calculated
+ values) will be cast if necessary.
+ ddof : int, optional
+ Means Delta Degrees of Freedom. The divisor used in calculations
+ is ``N - ddof``, where ``N`` represents the number of elements.
+ By default `ddof` is zero.
+ passed through to the `std` method of sub-classes of
+ Elements to include in the standard deviation.
+ standard_deviation : ndarray, see dtype parameter above.
+ If `out` is None, return a new array containing the standard deviation,
+ otherwise return a reference to the output array.
+ var, mean, nanmean, nanstd, nanvar
+ The standard deviation is the square root of the average of the squared
+ deviations from the mean, i.e., ``std = sqrt(mean(x))``, where
+ ``x = abs(a - a.mean())**2``.
+ The average squared deviation is typically calculated as ``x.sum() / N``,
+ where ``N = len(x)``. If, however, `ddof` is specified, the divisor
+ ``N - ddof`` is used instead. In standard statistical practice, ``ddof=1``
+ provides an unbiased estimator of the variance of the infinite population.
+ ``ddof=0`` provides a maximum likelihood estimate of the variance for
+ normally distributed variables. The standard deviation computed in this
+ function is the square root of the estimated variance, so even with
+ ``ddof=1``, it will not be an unbiased estimate of the standard deviation
+ per se.
+ Note that, for complex numbers, `std` takes the absolute
+ value before squaring, so that the result is always real and nonnegative.
+ For floating-point input, the *std* is computed using the same
+ precision the input has. Depending on the input data, this can cause
+ the results to be inaccurate, especially for float32 (see example below).
+ Specifying a higher-accuracy accumulator using the `dtype` keyword can
+ alleviate this issue.
+ >>> np.std(a)
+ 1.1180339887498949 # may vary
+ >>> np.std(a, axis=0)
+ >>> np.std(a, axis=1)
+ array([0.5, 0.5])
+ In single precision, std() can be inaccurate:
+ 0.45000005
+ Computing the standard deviation in float64 is more accurate:
+ >>> np.std(a, dtype=np.float64)
+ 0.44999999925494177 # may vary
+ >>> a = np.array([[14, 8, 11, 10], [7, 9, 10, 11], [10, 15, 5, 10]])
+ 2.614064523559687 # may vary
+ >>> np.std(a, where=[[True], [True], [False]])
+ std = a.std
+ return std(axis=axis, dtype=dtype, out=out, ddof=ddof, **kwargs)
+ return _methods._std(a, axis=axis, dtype=dtype, out=out, ddof=ddof,
+ **kwargs)
+def _var_dispatcher(a, axis=None, dtype=None, out=None, ddof=None,
+@array_function_dispatch(_var_dispatcher)
+def var(a, axis=None, dtype=None, out=None, ddof=0, keepdims=np._NoValue, *,
+ Compute the variance along the specified axis.
+ Returns the variance of the array elements, a measure of the spread of a
+ distribution. The variance is computed for the flattened array by
+ default, otherwise over the specified axis.
+ Array containing numbers whose variance is desired. If `a` is not an
+ Axis or axes along which the variance is computed. The default is to
+ compute the variance of the flattened array.
+ If this is a tuple of ints, a variance is performed over multiple axes,
+ Type to use in computing the variance. For arrays of integer type
+ the default is `float64`; for arrays of float types it is the same as
+ the array type.
+ the same shape as the expected output, but the type is cast if
+ "Delta Degrees of Freedom": the divisor used in the calculation is
+ ``N - ddof``, where ``N`` represents the number of elements. By
+ default `ddof` is zero.
+ passed through to the `var` method of sub-classes of
+ Elements to include in the variance. See `~numpy.ufunc.reduce` for
+ variance : ndarray, see dtype parameter above
+ If ``out=None``, returns a new array containing the variance;
+ otherwise, a reference to the output array is returned.
+ std, mean, nanmean, nanstd, nanvar
+ The variance is the average of the squared deviations from the mean,
+ i.e., ``var = mean(x)``, where ``x = abs(a - a.mean())**2``.
+ The mean is typically calculated as ``x.sum() / N``, where ``N = len(x)``.
+ If, however, `ddof` is specified, the divisor ``N - ddof`` is used
+ instead. In standard statistical practice, ``ddof=1`` provides an
+ unbiased estimator of the variance of a hypothetical infinite population.
+ normally distributed variables.
+ Note that for complex numbers, the absolute value is taken before
+ squaring, so that the result is always real and nonnegative.
+ For floating-point input, the variance is computed using the same
+ the results to be inaccurate, especially for `float32` (see example
+ below). Specifying a higher-accuracy accumulator using the ``dtype``
+ keyword can alleviate this issue.
+ >>> np.var(a)
+ 1.25
+ >>> np.var(a, axis=0)
+ >>> np.var(a, axis=1)
+ array([0.25, 0.25])
+ In single precision, var() can be inaccurate:
+ 0.20250003
+ Computing the variance in float64 is more accurate:
+ >>> np.var(a, dtype=np.float64)
+ 0.20249999932944759 # may vary
+ >>> ((1-0.55)**2 + (0.1-0.55)**2)/2
+ 0.2025
+ 6.833333333333333 # may vary
+ >>> np.var(a, where=[[True], [True], [False]])
+ var = a.var
+ return var(axis=axis, dtype=dtype, out=out, ddof=ddof, **kwargs)
+ return _methods._var(a, axis=axis, dtype=dtype, out=out, ddof=ddof,
+# Aliases of other functions. These have their own definitions only so that
+# they can have unique docstrings.
+def round_(a, decimals=0, out=None):
+ Round an array to the given number of decimals.
+ around : equivalent function; see for details.
+ return around(a, decimals=decimals, out=out)
+@array_function_dispatch(_prod_dispatcher, verify=False)
+def product(*args, **kwargs):
+ prod : equivalent function; see for details.
+ return prod(*args, **kwargs)
+@array_function_dispatch(_cumprod_dispatcher, verify=False)
+def cumproduct(*args, **kwargs):
+ Return the cumulative product over the given axis.
+ cumprod : equivalent function; see for details.
+ return cumprod(*args, **kwargs)
+@array_function_dispatch(_any_dispatcher, verify=False)
+def sometrue(*args, **kwargs):
+ Check whether some values are true.
+ Refer to `any` for full documentation.
+ any : equivalent function; see for details.
+ return any(*args, **kwargs)
+@array_function_dispatch(_all_dispatcher, verify=False)
+def alltrue(*args, **kwargs):
+ Check if all elements of input array are true.
+ numpy.all : Equivalent function; see for details.
+ return all(*args, **kwargs)
@@ -0,0 +1,357 @@
+from typing import Optional, Union, Sequence, Tuple, Any, overload, TypeVar
+ signedinteger,
+ bool_,
+ generic,
+ _OrderKACF,
+ _OrderACF,
+ _ArrayLikeBool,
+ _ArrayLikeIntOrBool,
+ _ModeKind,
+ _PartitionKind,
+ _SortKind,
+ _SortSide,
+# Various annotations for scalars
+# While dt.datetime and dt.timedelta are not technically part of NumPy,
+# they are one of the rare few builtin scalars which serve as valid return types.
+# See https://github.com/numpy/numpy-stubs/pull/67#discussion_r412604113.
+_ScalarNumpy = Union[generic, dt.datetime, dt.timedelta]
+_ScalarBuiltin = Union[str, bytes, dt.date, dt.timedelta, bool, int, float, complex]
+_Scalar = Union[_ScalarBuiltin, _ScalarNumpy]
+# Integers and booleans can generally be used interchangeably
+_ScalarGeneric = TypeVar("_ScalarGeneric", bound=generic)
+# The signature of take() follows a common theme with its overloads:
+# 1. A generic comes in; the same generic comes out
+# 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
+def take(
+ axis: Optional[int] = ...,
+ out: Optional[ndarray] = ...,
+) -> Any: ...
+def reshape(
+ newshape: _ShapeLike,
+ order: _OrderACF = ...,
+def choose(
+ a: _ArrayLikeIntOrBool,
+def repeat(
+def put(
+ a: ndarray,
+ ind: _ArrayLikeIntOrBool,
+) -> None: ...
+def swapaxes(
+ axis1: int,
+ axis2: int,
+def transpose(
+ axes: Union[None, Sequence[int], ndarray] = ...
+def partition(
+def argpartition(
+def sort(
+def argsort(
+def argmax(
+) -> signedinteger[Any]: ...
+def argmin(
+def searchsorted(
+ v: _Scalar,
+def resize(
+ new_shape: _ShapeLike,
+def squeeze(
+ a: _ScalarGeneric,
+) -> _ScalarGeneric: ...
+def diagonal(
+ axis1: int = ...,
+ axis2: int = ..., # >= 2D array
+def trace(
+ a: ArrayLike, # >= 2D array
+ axis2: int = ...,
+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
+def clip(
+ a_min: ArrayLike,
+ a_max: Optional[ArrayLike],
+ a_min: None,
+ a_max: ArrayLike,
+def sum(
+def all(
+) -> bool_: ...
+def any(
+def cumsum(
+def ptp(
+def amax(
+def amin(
+# TODO: `np.prod()``: For object arrays `initial` does not necessarily
+# have to be a numerical scalar.
+# The only requirement is that it is compatible
+# with the `.__mul__()` method(s) of the passed array's elements.
+# Note that the same situation holds for all wrappers around
+# `np.ufunc.reduce`, e.g. `np.sum()` (`.__add__()`).
+def prod(
+def cumprod(
+def ndim(a: ArrayLike) -> int: ...
+def size(a: ArrayLike, axis: Optional[int] = ...) -> int: ...
+def around(
+ decimals: int = ...,
+def mean(
+def std(
+def var(
@@ -0,0 +1,529 @@
+from . import numeric as _nx
+from .numeric import result_type, NaN, asanyarray, ndim
+from numpy.core.multiarray import add_docstring
+__all__ = ['logspace', 'linspace', 'geomspace']
+def _linspace_dispatcher(start, stop, num=None, endpoint=None, retstep=None,
+ dtype=None, axis=None):
+ return (start, stop)
+@array_function_dispatch(_linspace_dispatcher)
+def linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None,
+ axis=0):
+ Return evenly spaced numbers over a specified interval.
+ Returns `num` evenly spaced samples, calculated over the
+ interval [`start`, `stop`].
+ The endpoint of the interval can optionally be excluded.
+ .. versionchanged:: 1.16.0
+ Non-scalar `start` and `stop` are now supported.
+ .. versionchanged:: 1.20.0
+ Values are rounded towards ``-inf`` instead of ``0`` when an
+ integer ``dtype`` is specified. The old behavior can
+ still be obtained with ``np.linspace(start, stop, num).astype(int)``
+ start : array_like
+ The starting value of the sequence.
+ stop : array_like
+ The end value of the sequence, unless `endpoint` is set to False.
+ In that case, the sequence consists of all but the last of ``num + 1``
+ evenly spaced samples, so that `stop` is excluded. Note that the step
+ size changes when `endpoint` is False.
+ num : int, optional
+ Number of samples to generate. Default is 50. Must be non-negative.
+ endpoint : bool, optional
+ If True, `stop` is the last sample. Otherwise, it is not included.
+ Default is True.
+ retstep : bool, optional
+ If True, return (`samples`, `step`), where `step` is the spacing
+ between samples.
+ The type of the output array. If `dtype` is not given, the data type
+ is inferred from `start` and `stop`. The inferred dtype will never be
+ an integer; `float` is chosen even if the arguments would produce an
+ array of integers.
+ The axis in the result to store the samples. Relevant only if start
+ or stop are array-like. By default (0), the samples will be along a
+ new axis inserted at the beginning. Use -1 to get an axis at the end.
+ .. versionadded:: 1.16.0
+ samples : ndarray
+ There are `num` equally spaced samples in the closed interval
+ ``[start, stop]`` or the half-open interval ``[start, stop)``
+ (depending on whether `endpoint` is True or False).
+ step : float, optional
+ Only returned if `retstep` is True
+ Size of spacing between samples.
+ arange : Similar to `linspace`, but uses a step size (instead of the
+ number of samples).
+ geomspace : Similar to `linspace`, but with numbers spaced evenly on a log
+ scale (a geometric progression).
+ logspace : Similar to `geomspace`, but with the end points specified as
+ logarithms.
+ >>> np.linspace(2.0, 3.0, num=5)
+ array([2. , 2.25, 2.5 , 2.75, 3. ])
+ >>> np.linspace(2.0, 3.0, num=5, endpoint=False)
+ array([2. , 2.2, 2.4, 2.6, 2.8])
+ >>> np.linspace(2.0, 3.0, num=5, retstep=True)
+ (array([2. , 2.25, 2.5 , 2.75, 3. ]), 0.25)
+ Graphical illustration:
+ >>> import matplotlib.pyplot as plt
+ >>> N = 8
+ >>> y = np.zeros(N)
+ >>> x1 = np.linspace(0, 10, N, endpoint=True)
+ >>> x2 = np.linspace(0, 10, N, endpoint=False)
+ >>> plt.plot(x1, y, 'o')
+ [<matplotlib.lines.Line2D object at 0x...>]
+ >>> plt.plot(x2, y + 0.5, 'o')
+ >>> plt.ylim([-0.5, 1])
+ (-0.5, 1)
+ >>> plt.show()
+ num = operator.index(num)
+ raise ValueError("Number of samples, %s, must be non-negative." % num)
+ div = (num - 1) if endpoint else num
+ # Convert float/complex array scalars to float, gh-3504
+ # and make sure one can use variables that have an __array_interface__, gh-6634
+ start = asanyarray(start) * 1.0
+ stop = asanyarray(stop) * 1.0
+ dt = result_type(start, stop, float(num))
+ dtype = dt
+ delta = stop - start
+ y = _nx.arange(0, num, dtype=dt).reshape((-1,) + (1,) * ndim(delta))
+ # In-place multiplication y *= delta/div is faster, but prevents the multiplicant
+ # from overriding what class is produced, and thus prevents, e.g. use of Quantities,
+ # see gh-7142. Hence, we multiply in place only for standard scalar types.
+ _mult_inplace = _nx.isscalar(delta)
+ if div > 0:
+ step = delta / div
+ if _nx.any(step == 0):
+ # Special handling for denormal numbers, gh-5437
+ y /= div
+ if _mult_inplace:
+ y *= delta
+ y = y * delta
+ y *= step
+ y = y * step
+ # sequences with 0 items or 1 item with endpoint=True (i.e. div <= 0)
+ # have an undefined step
+ step = NaN
+ # Multiply with delta to allow possible override of output class.
+ y += start
+ if endpoint and num > 1:
+ y[-1] = stop
+ if axis != 0:
+ y = _nx.moveaxis(y, 0, axis)
+ if _nx.issubdtype(dtype, _nx.integer):
+ _nx.floor(y, out=y)
+ if retstep:
+ return y.astype(dtype, copy=False), step
+ return y.astype(dtype, copy=False)
+def _logspace_dispatcher(start, stop, num=None, endpoint=None, base=None,
+@array_function_dispatch(_logspace_dispatcher)
+def logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None,
+ Return numbers spaced evenly on a log scale.
+ In linear space, the sequence starts at ``base ** start``
+ (`base` to the power of `start`) and ends with ``base ** stop``
+ (see `endpoint` below).
+ ``base ** start`` is the starting value of the sequence.
+ ``base ** stop`` is the final value of the sequence, unless `endpoint`
+ is False. In that case, ``num + 1`` values are spaced over the
+ interval in log-space, of which all but the last (a sequence of
+ length `num`) are returned.
+ num : integer, optional
+ Number of samples to generate. Default is 50.
+ endpoint : boolean, optional
+ If true, `stop` is the last sample. Otherwise, it is not included.
+ base : array_like, optional
+ The base of the log space. The step size between the elements in
+ ``ln(samples) / ln(base)`` (or ``log_base(samples)``) is uniform.
+ Default is 10.0.
+ is inferred from `start` and `stop`. The inferred type will never be
+ `num` samples, equally spaced on a log scale.
+ arange : Similar to linspace, with the step size specified instead of the
+ number of samples. Note that, when used with a float endpoint, the
+ endpoint may or may not be included.
+ linspace : Similar to logspace, but with the samples uniformly distributed
+ in linear space, instead of log space.
+ geomspace : Similar to logspace, but with endpoints specified directly.
+ Logspace is equivalent to the code
+ >>> y = np.linspace(start, stop, num=num, endpoint=endpoint)
+ >>> power(base, y).astype(dtype)
+ >>> np.logspace(2.0, 3.0, num=4)
+ array([ 100. , 215.443469 , 464.15888336, 1000. ])
+ >>> np.logspace(2.0, 3.0, num=4, endpoint=False)
+ array([100. , 177.827941 , 316.22776602, 562.34132519])
+ >>> np.logspace(2.0, 3.0, num=4, base=2.0)
+ array([4. , 5.0396842 , 6.34960421, 8. ])
+ >>> N = 10
+ >>> x1 = np.logspace(0.1, 1, N, endpoint=True)
+ >>> x2 = np.logspace(0.1, 1, N, endpoint=False)
+ y = linspace(start, stop, num=num, endpoint=endpoint, axis=axis)
+ return _nx.power(base, y)
+ return _nx.power(base, y).astype(dtype, copy=False)
+def _geomspace_dispatcher(start, stop, num=None, endpoint=None, dtype=None,
+ axis=None):
+@array_function_dispatch(_geomspace_dispatcher)
+def geomspace(start, stop, num=50, endpoint=True, dtype=None, axis=0):
+ Return numbers spaced evenly on a log scale (a geometric progression).
+ This is similar to `logspace`, but with endpoints specified directly.
+ Each output sample is a constant multiple of the previous.
+ The final value of the sequence, unless `endpoint` is False.
+ In that case, ``num + 1`` values are spaced over the
+ logspace : Similar to geomspace, but with endpoints specified using log
+ and base.
+ linspace : Similar to geomspace, but with arithmetic instead of geometric
+ progression.
+ number of samples.
+ If the inputs or dtype are complex, the output will follow a logarithmic
+ spiral in the complex plane. (There are an infinite number of spirals
+ passing through two points; the output will follow the shortest such path.)
+ >>> np.geomspace(1, 1000, num=4)
+ array([ 1., 10., 100., 1000.])
+ >>> np.geomspace(1, 1000, num=3, endpoint=False)
+ array([ 1., 10., 100.])
+ >>> np.geomspace(1, 1000, num=4, endpoint=False)
+ array([ 1. , 5.62341325, 31.6227766 , 177.827941 ])
+ >>> np.geomspace(1, 256, num=9)
+ array([ 1., 2., 4., 8., 16., 32., 64., 128., 256.])
+ Note that the above may not produce exact integers:
+ >>> np.geomspace(1, 256, num=9, dtype=int)
+ array([ 1, 2, 4, 7, 16, 32, 63, 127, 256])
+ >>> np.around(np.geomspace(1, 256, num=9)).astype(int)
+ array([ 1, 2, 4, 8, 16, 32, 64, 128, 256])
+ Negative, decreasing, and complex inputs are allowed:
+ >>> np.geomspace(1000, 1, num=4)
+ array([1000., 100., 10., 1.])
+ >>> np.geomspace(-1000, -1, num=4)
+ array([-1000., -100., -10., -1.])
+ >>> np.geomspace(1j, 1000j, num=4) # Straight line
+ array([0. +1.j, 0. +10.j, 0. +100.j, 0.+1000.j])
+ >>> np.geomspace(-1+0j, 1+0j, num=5) # Circle
+ array([-1.00000000e+00+1.22464680e-16j, -7.07106781e-01+7.07106781e-01j,
+ 6.12323400e-17+1.00000000e+00j, 7.07106781e-01+7.07106781e-01j,
+ 1.00000000e+00+0.00000000e+00j])
+ Graphical illustration of ``endpoint`` parameter:
+ >>> plt.semilogx(np.geomspace(1, 1000, N, endpoint=True), y + 1, 'o')
+ >>> plt.semilogx(np.geomspace(1, 1000, N, endpoint=False), y + 2, 'o')
+ >>> plt.axis([0.5, 2000, 0, 3])
+ [0.5, 2000, 0, 3]
+ >>> plt.grid(True, color='0.7', linestyle='-', which='both', axis='both')
+ start = asanyarray(start)
+ stop = asanyarray(stop)
+ if _nx.any(start == 0) or _nx.any(stop == 0):
+ raise ValueError('Geometric sequence cannot include zero')
+ dt = result_type(start, stop, float(num), _nx.zeros((), dtype))
+ # complex to dtype('complex128'), for instance
+ dtype = _nx.dtype(dtype)
+ # Promote both arguments to the same dtype in case, for instance, one is
+ # complex and another is negative and log would produce NaN otherwise.
+ # Copy since we may change things in-place further down.
+ start = start.astype(dt, copy=True)
+ stop = stop.astype(dt, copy=True)
+ out_sign = _nx.ones(_nx.broadcast(start, stop).shape, dt)
+ # Avoid negligible real or imaginary parts in output by rotating to
+ # positive real, calculating, then undoing rotation
+ if _nx.issubdtype(dt, _nx.complexfloating):
+ all_imag = (start.real == 0.) & (stop.real == 0.)
+ if _nx.any(all_imag):
+ start[all_imag] = start[all_imag].imag
+ stop[all_imag] = stop[all_imag].imag
+ out_sign[all_imag] = 1j
+ both_negative = (_nx.sign(start) == -1) & (_nx.sign(stop) == -1)
+ if _nx.any(both_negative):
+ _nx.negative(start, out=start, where=both_negative)
+ _nx.negative(stop, out=stop, where=both_negative)
+ _nx.negative(out_sign, out=out_sign, where=both_negative)
+ log_start = _nx.log10(start)
+ log_stop = _nx.log10(stop)
+ result = logspace(log_start, log_stop, num=num,
+ endpoint=endpoint, base=10.0, dtype=dtype)
+ # Make sure the endpoints match the start and stop arguments. This is
+ # necessary because np.exp(np.log(x)) is not necessarily equal to x.
+ if num > 0:
+ result[0] = start
+ if num > 1 and endpoint:
+ result[-1] = stop
+ result = out_sign * result
+ result = _nx.moveaxis(result, 0, axis)
+ return result.astype(dtype, copy=False)
+def _needs_add_docstring(obj):
+ Returns true if the only way to set the docstring of `obj` from python is
+ via add_docstring.
+ This function errs on the side of being overly conservative.
+ Py_TPFLAGS_HEAPTYPE = 1 << 9
+ if isinstance(obj, (types.FunctionType, types.MethodType, property)):
+ if isinstance(obj, type) and obj.__flags__ & Py_TPFLAGS_HEAPTYPE:
+def _add_docstring(obj, doc, warn_on_python):
+ if warn_on_python and not _needs_add_docstring(obj):
+ "add_newdoc was used on a pure-python object {}. "
+ "Prefer to attach it directly to the source."
+ .format(obj),
+ UserWarning,
+ stacklevel=3)
+ add_docstring(obj, doc)
+def add_newdoc(place, obj, doc, warn_on_python=True):
+ Add documentation to an existing object, typically one defined in C
+ The purpose is to allow easier editing of the docstrings without requiring
+ a re-compile. This exists primarily for internal use within numpy itself.
+ place : str
+ The absolute name of the module to import from
+ obj : str
+ The name of the object to add documentation to, typically a class or
+ function name
+ doc : {str, Tuple[str, str], List[Tuple[str, str]]}
+ If a string, the documentation to apply to `obj`
+ If a tuple, then the first element is interpreted as an attribute of
+ `obj` and the second as the docstring to apply - ``(method, docstring)``
+ If a list, then each element of the list should be a tuple of length
+ two - ``[(method1, docstring1), (method2, docstring2), ...]``
+ warn_on_python : bool
+ If True, the default, emit `UserWarning` if this is used to attach
+ documentation to a pure-python object.
+ This routine never raises an error if the docstring can't be written, but
+ will raise an error if the object being documented does not exist.
+ This routine cannot modify read-only docstrings, as appear
+ in new-style classes or built-in functions. Because this
+ routine never raises an error the caller must check manually
+ that the docstrings were changed.
+ Since this function grabs the ``char *`` from a c-level str object and puts
+ it into the ``tp_doc`` slot of the type of `obj`, it violates a number of
+ C-API best-practices, by:
+ - modifying a `PyTypeObject` after calling `PyType_Ready`
+ - calling `Py_INCREF` on the str and losing the reference, so the str
+ will never be released
+ If possible it should be avoided.
+ new = getattr(__import__(place, globals(), {}, [obj]), obj)
+ if isinstance(doc, str):
+ _add_docstring(new, doc.strip(), warn_on_python)
+ elif isinstance(doc, tuple):
+ attr, docstring = doc
+ _add_docstring(getattr(new, attr), docstring.strip(), warn_on_python)
+ elif isinstance(doc, list):
+ for attr, docstring in doc:
@@ -0,0 +1,58 @@
+from typing import overload, Tuple, Union, Sequence, Any
+from numpy import ndarray
+from numpy.typing import ArrayLike, DTypeLike, _SupportsArray, _NumberLike
+ from typing import SupportsIndex, Literal
+ from typing_extensions import Literal, Protocol
+# TODO: wait for support for recursive types
+_ArrayLikeNested = Sequence[Sequence[Any]]
+_ArrayLikeNumber = Union[
+ _NumberLike, Sequence[_NumberLike], ndarray, _SupportsArray, _ArrayLikeNested
+def linspace(
+ start: _ArrayLikeNumber,
+ stop: _ArrayLikeNumber,
+ num: SupportsIndex = ...,
+ endpoint: bool = ...,
+ retstep: Literal[False] = ...,
+ retstep: Literal[True] = ...,
+) -> Tuple[ndarray, Any]: ...
+def logspace(
+ base: _ArrayLikeNumber = ...,
+def geomspace(
@@ -0,0 +1,239 @@
+import genapi
+from genapi import \
+ TypeApi, GlobalVarApi, FunctionApi, BoolValuesApi
+import numpy_api
+# use annotated api when running under cpychecker
+h_template = r"""
+#if defined(_MULTIARRAYMODULE) || defined(WITH_CPYCHECKER_STEALS_REFERENCE_TO_ARG_ATTRIBUTE)
+typedef struct {
+ PyObject_HEAD
+ npy_bool obval;
+} PyBoolScalarObject;
+extern NPY_NO_EXPORT PyTypeObject PyArrayMapIter_Type;
+extern NPY_NO_EXPORT PyTypeObject PyArrayNeighborhoodIter_Type;
+extern NPY_NO_EXPORT PyBoolScalarObject _PyArrayScalar_BoolValues[2];
+%s
+#else
+#if defined(PY_ARRAY_UNIQUE_SYMBOL)
+#define PyArray_API PY_ARRAY_UNIQUE_SYMBOL
+#endif
+#if defined(NO_IMPORT) || defined(NO_IMPORT_ARRAY)
+extern void **PyArray_API;
+void **PyArray_API;
+static void **PyArray_API=NULL;
+#if !defined(NO_IMPORT_ARRAY) && !defined(NO_IMPORT)
+static int
+_import_array(void)
+ int st;
+ PyObject *numpy = PyImport_ImportModule("numpy.core._multiarray_umath");
+ PyObject *c_api = NULL;
+ if (numpy == NULL) {
+ return -1;
+ c_api = PyObject_GetAttrString(numpy, "_ARRAY_API");
+ Py_DECREF(numpy);
+ if (c_api == NULL) {
+ PyErr_SetString(PyExc_AttributeError, "_ARRAY_API not found");
+ if (!PyCapsule_CheckExact(c_api)) {
+ PyErr_SetString(PyExc_RuntimeError, "_ARRAY_API is not PyCapsule object");
+ Py_DECREF(c_api);
+ PyArray_API = (void **)PyCapsule_GetPointer(c_api, NULL);
+ if (PyArray_API == NULL) {
+ PyErr_SetString(PyExc_RuntimeError, "_ARRAY_API is NULL pointer");
+ /* Perform runtime check of C API version */
+ if (NPY_VERSION != PyArray_GetNDArrayCVersion()) {
+ PyErr_Format(PyExc_RuntimeError, "module compiled against "\
+ "ABI version 0x%%x but this version of numpy is 0x%%x", \
+ (int) NPY_VERSION, (int) PyArray_GetNDArrayCVersion());
+ if (NPY_FEATURE_VERSION > PyArray_GetNDArrayCFeatureVersion()) {
+ "API version 0x%%x but this version of numpy is 0x%%x", \
+ (int) NPY_FEATURE_VERSION, (int) PyArray_GetNDArrayCFeatureVersion());
+ /*
+ * Perform runtime check of endianness and check it matches the one set by
+ * the headers (npy_endian.h) as a safeguard
+ */
+ st = PyArray_GetEndianness();
+ if (st == NPY_CPU_UNKNOWN_ENDIAN) {
+ PyErr_Format(PyExc_RuntimeError, "FATAL: module compiled as unknown endian");
+#if NPY_BYTE_ORDER == NPY_BIG_ENDIAN
+ if (st != NPY_CPU_BIG) {
+ PyErr_Format(PyExc_RuntimeError, "FATAL: module compiled as "\
+ "big endian, but detected different endianness at runtime");
+#elif NPY_BYTE_ORDER == NPY_LITTLE_ENDIAN
+ if (st != NPY_CPU_LITTLE) {
+ "little endian, but detected different endianness at runtime");
+ return 0;
+#define import_array() {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); return NULL; } }
+#define import_array1(ret) {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); return ret; } }
+#define import_array2(msg, ret) {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, msg); return ret; } }
+c_template = r"""
+/* These pointers will be stored in the C-object for use in other
+ extension modules
+*/
+void *PyArray_API[] = {
+};
+c_api_header = """
+===========
+NumPy C-API
+def generate_api(output_dir, force=False):
+ basename = 'multiarray_api'
+ h_file = os.path.join(output_dir, '__%s.h' % basename)
+ c_file = os.path.join(output_dir, '__%s.c' % basename)
+ d_file = os.path.join(output_dir, '%s.txt' % basename)
+ targets = (h_file, c_file, d_file)
+ sources = numpy_api.multiarray_api
+ if (not force and not genapi.should_rebuild(targets, [numpy_api.__file__, __file__])):
+ return targets
+ do_generate_api(targets, sources)
+def do_generate_api(targets, sources):
+ header_file = targets[0]
+ c_file = targets[1]
+ doc_file = targets[2]
+ global_vars = sources[0]
+ scalar_bool_values = sources[1]
+ types_api = sources[2]
+ multiarray_funcs = sources[3]
+ multiarray_api = sources[:]
+ module_list = []
+ extension_list = []
+ init_list = []
+ # Check multiarray api indexes
+ multiarray_api_index = genapi.merge_api_dicts(multiarray_api)
+ genapi.check_api_dict(multiarray_api_index)
+ 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 = {}
+ for f in numpyapi_list:
+ name = f.name
+ index = multiarray_funcs[name][0]
+ annotations = multiarray_funcs[name][1:]
+ multiarray_api_dict[f.name] = FunctionApi(f.name, index, annotations,
+ f.return_type,
+ f.args, api_name)
+ for name, val in global_vars.items():
+ index, type = val
+ multiarray_api_dict[name] = GlobalVarApi(name, index, type, api_name)
+ for name, val in scalar_bool_values.items():
+ index = val[0]
+ multiarray_api_dict[name] = BoolValuesApi(name, index, api_name)
+ for name, val in types_api.items():
+ internal_type = None if len(val) == 1 else val[1]
+ multiarray_api_dict[name] = TypeApi(
+ name, index, 'PyTypeObject', api_name, internal_type)
+ if len(multiarray_api_dict) != len(multiarray_api_index):
+ keys_dict = set(multiarray_api_dict.keys())
+ keys_index = set(multiarray_api_index.keys())
+ raise AssertionError(
+ "Multiarray API size mismatch - "
+ "index has extra keys {}, dict has extra keys {}"
+ .format(keys_index - keys_dict, keys_dict - keys_index)
+ for name, index in genapi.order_dict(multiarray_api_index):
+ api_item = multiarray_api_dict[name]
+ extension_list.append(api_item.define_from_array_api_string())
+ init_list.append(api_item.array_api_define())
+ module_list.append(api_item.internal_define())
+ # Write to header
+ s = h_template % ('\n'.join(module_list), '\n'.join(extension_list))
+ genapi.write_file(header_file, s)
+ # Write to c-code
+ s = c_template % ',\n'.join(init_list)
+ genapi.write_file(c_file, s)
+ # write to documentation
+ s = c_api_header
+ for func in numpyapi_list:
+ s += func.to_ReST()
+ s += '\n\n'
+ genapi.write_file(doc_file, s)
@@ -0,0 +1,564 @@
+"""Machine limits for Float32 and Float64 and (long double) if available...
+__all__ = ['finfo', 'iinfo']
+from .machar import MachAr
+from . import numerictypes as ntypes
+from .numeric import array, inf
+from .umath import log10, exp2
+def _fr0(a):
+ """fix rank-0 --> rank-1"""
+ if a.ndim == 0:
+ a = a.copy()
+ a.shape = (1,)
+def _fr1(a):
+ """fix rank > 0 --> rank-0"""
+ if a.size == 1:
+ a.shape = ()
+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']
+ # 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)
+ 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)
+_convert_to_float = {
+ ntypes.csingle: ntypes.single,
+ ntypes.complex_: ntypes.float_,
+ ntypes.clongfloat: ntypes.longfloat
+# Parameters for creating MachAr / MachAr-like objects
+_title_fmt = 'numpy {} precision floating point number'
+_MACHAR_PARAMS = {
+ ntypes.double: dict(
+ itype = ntypes.int64,
+ fmt = '%24.16e',
+ title = _title_fmt.format('double')),
+ ntypes.single: dict(
+ itype = ntypes.int32,
+ fmt = '%15.7e',
+ title = _title_fmt.format('single')),
+ ntypes.longdouble: dict(
+ itype = ntypes.longlong,
+ fmt = '%s',
+ title = _title_fmt.format('long double')),
+ ntypes.half: dict(
+ itype = ntypes.int16,
+ fmt = '%12.5e',
+ title = _title_fmt.format('half'))}
+# Key to identify the floating point type. Key is result of
+# ftype('-0.1').newbyteorder('<').tobytes()
+# See:
+# https://perl5.git.perl.org/perl.git/blob/3118d7d684b56cbeb702af874f4326683c45f045:/Configure
+_KNOWN_TYPES = {}
+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.
+ f16 = ntypes.float16
+ float16_ma = MachArLike(f16,
+ machep=-10,
+ negep=-11,
+ minexp=-14,
+ maxexp=16,
+ it=10,
+ iexp=5,
+ ibeta=2,
+ irnd=5,
+ ngrd=0,
+ eps=exp2(f16(-10)),
+ epsneg=exp2(f16(-11)),
+ huge=f16(65504),
+ tiny=f16(2 ** -14))
+ _register_type(float16_ma, b'f\xae')
+ _float_ma[16] = float16_ma
+ # Known parameters for float32
+ f32 = ntypes.float32
+ float32_ma = MachArLike(f32,
+ machep=-23,
+ negep=-24,
+ minexp=-126,
+ maxexp=128,
+ it=23,
+ iexp=8,
+ eps=exp2(f32(-23)),
+ epsneg=exp2(f32(-24)),
+ huge=f32((1 - 2 ** -24) * 2**128),
+ tiny=exp2(f32(-126)))
+ _register_type(float32_ma, b'\xcd\xcc\xcc\xbd')
+ _float_ma[32] = float32_ma
+ # Known parameters for float64
+ f64 = ntypes.float64
+ epsneg_f64 = 2.0 ** -53.0
+ tiny_f64 = 2.0 ** -1022.0
+ float64_ma = MachArLike(f64,
+ machep=-52,
+ negep=-53,
+ minexp=-1022,
+ maxexp=1024,
+ it=52,
+ iexp=11,
+ eps=2.0 ** -52.0,
+ epsneg=epsneg_f64,
+ huge=(1.0 - epsneg_f64) / tiny_f64 * f64(4),
+ tiny=tiny_f64)
+ _register_type(float64_ma, b'\x9a\x99\x99\x99\x99\x99\xb9\xbf')
+ _float_ma[64] = float64_ma
+ # Known parameters for IEEE 754 128-bit binary float
+ ld = ntypes.longdouble
+ epsneg_f128 = exp2(ld(-113))
+ tiny_f128 = exp2(ld(-16382))
+ # Ignore runtime error when this is not f128
+ with numeric.errstate(all='ignore'):
+ huge_f128 = (ld(1) - epsneg_f128) / tiny_f128 * ld(4)
+ float128_ma = MachArLike(ld,
+ machep=-112,
+ negep=-113,
+ minexp=-16382,
+ maxexp=16384,
+ it=112,
+ iexp=15,
+ eps=exp2(ld(-112)),
+ epsneg=epsneg_f128,
+ huge=huge_f128,
+ tiny=tiny_f128)
+ # IEEE 754 128-bit binary float
+ _register_type(float128_ma,
+ b'\x9a\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\xfb\xbf')
+ _float_ma[128] = float128_ma
+ # Known parameters for float80 (Intel 80-bit extended precision)
+ epsneg_f80 = exp2(ld(-64))
+ tiny_f80 = exp2(ld(-16382))
+ # Ignore runtime error when this is not f80
+ huge_f80 = (ld(1) - epsneg_f80) / tiny_f80 * ld(4)
+ float80_ma = MachArLike(ld,
+ machep=-63,
+ negep=-64,
+ it=63,
+ eps=exp2(ld(-63)),
+ epsneg=epsneg_f80,
+ huge=huge_f80,
+ tiny=tiny_f80)
+ # float80, first 10 bytes containing actual storage
+ _register_type(float80_ma, b'\xcd\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xfb\xbf')
+ _float_ma[80] = float80_ma
+ # Guessed / known parameters for double double; see:
+ # 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)
+ float_dd_ma = MachArLike(ld,
+ machep=-105,
+ negep=-106,
+ it=105,
+ eps=exp2(ld(-105)),
+ epsneg= exp2(ld(-106)),
+ huge=huge_dd,
+ tiny=exp2(ld(-1022)))
+ # 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')
+ # double double; high, low order (e.g. PPC 64 le)
+ b'\x9a\x99\x99\x99\x99\x99\xb9\xbf\x9a\x99\x99\x99\x99\x99Y<')
+ _float_ma['dd'] = float_dd_ma
+def _get_machar(ftype):
+ """ Get MachAr instance or MachAr-like instance
+ Get parameters for floating point type, by first trying signatures of
+ various known floating point types, then, if none match, attempting to
+ identify parameters by analysis.
+ ftype : class
+ Numpy floating point type class (e.g. ``np.float64``)
+ ma_like : instance of :class:`MachAr` or :class:`MachArLike`
+ Object giving floating point parameters for `ftype`.
+ Warns
+ UserWarning
+ If the binary signature of the float type is not in the dictionary of
+ known float types.
+ params = _MACHAR_PARAMS.get(ftype)
+ if params is None:
+ raise ValueError(repr(ftype))
+ # Detect known / suspected types
+ key = ftype('-0.1').newbyteorder('<').tobytes()
+ ma_like = None
+ if ftype == ntypes.longdouble:
+ # Could be 80 bit == 10 byte extended precision, where last bytes can
+ # be random garbage.
+ # Comparing first 10 bytes to pattern first to avoid branching on the
+ # random garbage.
+ ma_like = _KNOWN_TYPES.get(key[:10])
+ if ma_like is None:
+ ma_like = _KNOWN_TYPES.get(key)
+ if ma_like is not None:
+ return ma_like
+ # Fall back to parameter discovery
+ 'Signature {} for {} does not match any known type: '
+ 'falling back to type probe function'.format(key, ftype),
+ UserWarning, stacklevel=2)
+ return _discovered_machar(ftype)
+def _discovered_machar(ftype):
+ """ Create MachAr instance with found information on float types
+ return MachAr(lambda v: array([v], ftype),
+ lambda v:_fr0(v.astype(params['itype']))[0],
+ lambda v:array(_fr0(v)[0], ftype),
+ lambda v: params['fmt'] % array(_fr0(v)[0], ftype),
+ params['title'])
+class finfo:
+ finfo(dtype)
+ Machine limits for floating point types.
+ bits : int
+ The number of bits occupied by the type.
+ eps : float
+ The difference between 1.0 and the next smallest representable float
+ larger than 1.0. For example, for 64-bit binary floats in the IEEE-754
+ standard, ``eps = 2**-52``, approximately 2.22e-16.
+ epsneg : float
+ less than 1.0. For example, for 64-bit binary floats in the IEEE-754
+ standard, ``epsneg = 2**-53``, approximately 1.11e-16.
+ iexp : int
+ The number of bits in the exponent portion of the floating point
+ representation.
+ machar : MachAr
+ The object which calculated these parameters and holds more
+ detailed information.
+ machep : int
+ The exponent that yields `eps`.
+ max : floating point number of the appropriate type
+ The largest representable number.
+ maxexp : int
+ The smallest positive power of the base (2) that causes overflow.
+ min : floating point number of the appropriate type
+ The smallest representable number, typically ``-max``.
+ minexp : int
+ The most negative power of the base (2) consistent with there
+ being no leading 0's in the mantissa.
+ negep : int
+ The exponent that yields `epsneg`.
+ nexp : int
+ The number of bits in the exponent including its sign and bias.
+ nmant : int
+ The number of bits in the mantissa.
+ precision : int
+ The approximate number of decimal digits to which this kind of
+ float is precise.
+ resolution : floating point number of the appropriate type
+ The approximate decimal resolution of this type, i.e.,
+ ``10**-precision``.
+ tiny : float
+ The smallest positive floating point number with full precision
+ (see Notes).
+ dtype : float, dtype, or instance
+ Kind of floating point data-type about which to get information.
+ MachAr : The implementation of the tests that produce this information.
+ iinfo : The equivalent for integer data types.
+ spacing : The distance between a value and the nearest adjacent number
+ nextafter : The next floating point value after x1 towards x2
+ For developers of NumPy: do not instantiate this at the module level.
+ The initial calculation of these parameters is expensive and negatively
+ 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]_.
+ .. [1] IEEE Standard for Floating-Point Arithmetic, IEEE Std 754-2008,
+ pp.1-70, 2008, http://www.doi.org/10.1109/IEEESTD.2008.4610935
+ .. [2] Wikipedia, "Denormal Numbers",
+ https://en.wikipedia.org/wiki/Denormal_number
+ _finfo_cache = {}
+ def __new__(cls, dtype):
+ dtype = numeric.dtype(dtype)
+ # In case a float instance was given
+ dtype = numeric.dtype(type(dtype))
+ obj = cls._finfo_cache.get(dtype, None)
+ if obj is not None:
+ dtypes = [dtype]
+ newdtype = numeric.obj2sctype(dtype)
+ if newdtype is not dtype:
+ dtypes.append(newdtype)
+ dtype = newdtype
+ if not issubclass(dtype, numeric.inexact):
+ raise ValueError("data type %r not inexact" % (dtype))
+ if not issubclass(dtype, numeric.floating):
+ newdtype = _convert_to_float[dtype]
+ obj = object.__new__(cls)._init(dtype)
+ for dt in dtypes:
+ cls._finfo_cache[dt] = obj
+ def _init(self, dtype):
+ self.dtype = numeric.dtype(dtype)
+ machar = _get_machar(dtype)
+ for word in ['precision', 'iexp',
+ 'maxexp', 'minexp', 'negep',
+ 'machep']:
+ setattr(self, word, getattr(machar, word))
+ for word in ['tiny', 'resolution', 'epsneg']:
+ setattr(self, word, getattr(machar, word).flat[0])
+ self.bits = self.dtype.itemsize * 8
+ self.max = machar.huge.flat[0]
+ self.min = -self.max
+ self.eps = machar.eps.flat[0]
+ self.nexp = machar.iexp
+ self.nmant = machar.it
+ self.machar = machar
+ self._str_tiny = machar._str_xmin.strip()
+ self._str_max = machar._str_xmax.strip()
+ self._str_epsneg = machar._str_epsneg.strip()
+ self._str_eps = machar._str_eps.strip()
+ self._str_resolution = machar._str_resolution.strip()
+ fmt = (
+ 'Machine parameters for %(dtype)s\n'
+ '---------------------------------------------------------------\n'
+ 'precision = %(precision)3s resolution = %(_str_resolution)s\n'
+ 'machep = %(machep)6s eps = %(_str_eps)s\n'
+ 'negep = %(negep)6s epsneg = %(_str_epsneg)s\n'
+ 'minexp = %(minexp)6s tiny = %(_str_tiny)s\n'
+ 'maxexp = %(maxexp)6s max = %(_str_max)s\n'
+ 'nexp = %(nexp)6s min = -max\n'
+ return fmt % self.__dict__
+ c = self.__class__.__name__
+ d = self.__dict__.copy()
+ d['klass'] = c
+ return (("%(klass)s(resolution=%(resolution)s, min=-%(_str_max)s,"
+ " max=%(_str_max)s, dtype=%(dtype)s)") % d)
+class iinfo:
+ iinfo(type)
+ Machine limits for integer types.
+ min : int
+ The smallest integer expressible by the type.
+ max : int
+ The largest integer expressible by the type.
+ int_type : integer type, dtype, or instance
+ The kind of integer data type to get information about.
+ finfo : The equivalent for floating point data types.
+ With types:
+ >>> ii16 = np.iinfo(np.int16)
+ >>> ii16.min
+ -32768
+ >>> ii16.max
+ 32767
+ >>> ii32 = np.iinfo(np.int32)
+ >>> ii32.min
+ -2147483648
+ >>> ii32.max
+ 2147483647
+ With instances:
+ >>> ii32 = np.iinfo(np.int32(10))
+ _min_vals = {}
+ _max_vals = {}
+ def __init__(self, int_type):
+ self.dtype = numeric.dtype(int_type)
+ self.dtype = numeric.dtype(type(int_type))
+ self.kind = self.dtype.kind
+ self.key = "%s%d" % (self.kind, self.bits)
+ if self.kind not in 'iu':
+ raise ValueError("Invalid integer data type %r." % (self.kind,))
+ def min(self):
+ """Minimum value of given dtype."""
+ if self.kind == 'u':
+ return 0
+ val = iinfo._min_vals[self.key]
+ val = int(-(1 << (self.bits-1)))
+ iinfo._min_vals[self.key] = val
+ def max(self):
+ """Maximum value of given dtype."""
+ val = iinfo._max_vals[self.key]
+ val = int((1 << self.bits) - 1)
+ val = int((1 << (self.bits-1)) - 1)
+ iinfo._max_vals[self.key] = val
+ """String representation."""
+ 'min = %(min)s\n'
+ 'max = %(max)s\n'
+ return fmt % {'dtype': self.dtype, 'min': self.min, 'max': self.max}
+ return "%s(min=%s, max=%s, dtype=%s)" % (self.__class__.__name__,
+ self.min, self.max, self.dtype)
@@ -0,0 +1,1540 @@
+NPY_NO_EXPORT unsigned int PyArray_GetNDArrayCVersion \
+ (void);
+extern NPY_NO_EXPORT PyTypeObject PyBigArray_Type;
+extern NPY_NO_EXPORT PyTypeObject PyArray_Type;
+extern NPY_NO_EXPORT PyArray_DTypeMeta PyArrayDescr_TypeFull;
+#define PyArrayDescr_Type (*(PyTypeObject *)(&PyArrayDescr_TypeFull))
+extern NPY_NO_EXPORT PyTypeObject PyArrayFlags_Type;
+extern NPY_NO_EXPORT PyTypeObject PyArrayIter_Type;
+extern NPY_NO_EXPORT PyTypeObject PyArrayMultiIter_Type;
+extern NPY_NO_EXPORT int NPY_NUMUSERTYPES;
+extern NPY_NO_EXPORT PyTypeObject PyBoolArrType_Type;
+extern NPY_NO_EXPORT PyTypeObject PyGenericArrType_Type;
+extern NPY_NO_EXPORT PyTypeObject PyNumberArrType_Type;
+extern NPY_NO_EXPORT PyTypeObject PyIntegerArrType_Type;
+extern NPY_NO_EXPORT PyTypeObject PySignedIntegerArrType_Type;
+extern NPY_NO_EXPORT PyTypeObject PyUnsignedIntegerArrType_Type;
+extern NPY_NO_EXPORT PyTypeObject PyInexactArrType_Type;
+extern NPY_NO_EXPORT PyTypeObject PyFloatingArrType_Type;
+extern NPY_NO_EXPORT PyTypeObject PyComplexFloatingArrType_Type;
+extern NPY_NO_EXPORT PyTypeObject PyFlexibleArrType_Type;
+extern NPY_NO_EXPORT PyTypeObject PyCharacterArrType_Type;
+extern NPY_NO_EXPORT PyTypeObject PyByteArrType_Type;
+extern NPY_NO_EXPORT PyTypeObject PyShortArrType_Type;
+extern NPY_NO_EXPORT PyTypeObject PyIntArrType_Type;
+extern NPY_NO_EXPORT PyTypeObject PyLongArrType_Type;
+extern NPY_NO_EXPORT PyTypeObject PyLongLongArrType_Type;
+extern NPY_NO_EXPORT PyTypeObject PyUByteArrType_Type;
+extern NPY_NO_EXPORT PyTypeObject PyUShortArrType_Type;
+extern NPY_NO_EXPORT PyTypeObject PyUIntArrType_Type;
+extern NPY_NO_EXPORT PyTypeObject PyULongArrType_Type;
+extern NPY_NO_EXPORT PyTypeObject PyULongLongArrType_Type;
+extern NPY_NO_EXPORT PyTypeObject PyFloatArrType_Type;
+extern NPY_NO_EXPORT PyTypeObject PyDoubleArrType_Type;
+extern NPY_NO_EXPORT PyTypeObject PyLongDoubleArrType_Type;
+extern NPY_NO_EXPORT PyTypeObject PyCFloatArrType_Type;
+extern NPY_NO_EXPORT PyTypeObject PyCDoubleArrType_Type;
+extern NPY_NO_EXPORT PyTypeObject PyCLongDoubleArrType_Type;
+extern NPY_NO_EXPORT PyTypeObject PyObjectArrType_Type;
+extern NPY_NO_EXPORT PyTypeObject PyStringArrType_Type;
+extern NPY_NO_EXPORT PyTypeObject PyUnicodeArrType_Type;
+extern NPY_NO_EXPORT PyTypeObject PyVoidArrType_Type;
+NPY_NO_EXPORT int PyArray_SetNumericOps \
+ (PyObject *);
+NPY_NO_EXPORT PyObject * PyArray_GetNumericOps \
+NPY_NO_EXPORT int PyArray_INCREF \
+ (PyArrayObject *);
+NPY_NO_EXPORT int PyArray_XDECREF \
+NPY_NO_EXPORT void PyArray_SetStringFunction \
+ (PyObject *, int);
+NPY_NO_EXPORT PyArray_Descr * PyArray_DescrFromType \
+ (int);
+NPY_NO_EXPORT PyObject * PyArray_TypeObjectFromType \
+NPY_NO_EXPORT char * PyArray_Zero \
+NPY_NO_EXPORT char * PyArray_One \
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) NPY_GCC_NONNULL(2) PyObject * PyArray_CastToType \
+ (PyArrayObject *, PyArray_Descr *, int);
+NPY_NO_EXPORT int PyArray_CastTo \
+ (PyArrayObject *, PyArrayObject *);
+NPY_NO_EXPORT int PyArray_CastAnyTo \
+NPY_NO_EXPORT int PyArray_CanCastSafely \
+ (int, int);
+NPY_NO_EXPORT npy_bool PyArray_CanCastTo \
+ (PyArray_Descr *, PyArray_Descr *);
+NPY_NO_EXPORT int PyArray_ObjectType \
+NPY_NO_EXPORT PyArray_Descr * PyArray_DescrFromObject \
+ (PyObject *, PyArray_Descr *);
+NPY_NO_EXPORT PyArrayObject ** PyArray_ConvertToCommonType \
+ (PyObject *, int *);
+NPY_NO_EXPORT PyArray_Descr * PyArray_DescrFromScalar \
+NPY_NO_EXPORT PyArray_Descr * PyArray_DescrFromTypeObject \
+NPY_NO_EXPORT npy_intp PyArray_Size \
+NPY_NO_EXPORT PyObject * PyArray_Scalar \
+ (void *, PyArray_Descr *, PyObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) PyObject * PyArray_FromScalar \
+NPY_NO_EXPORT void PyArray_ScalarAsCtype \
+ (PyObject *, void *);
+NPY_NO_EXPORT int PyArray_CastScalarToCtype \
+ (PyObject *, void *, PyArray_Descr *);
+NPY_NO_EXPORT int PyArray_CastScalarDirect \
+ (PyObject *, PyArray_Descr *, void *, int);
+NPY_NO_EXPORT PyObject * PyArray_ScalarFromObject \
+NPY_NO_EXPORT PyArray_VectorUnaryFunc * PyArray_GetCastFunc \
+ (PyArray_Descr *, int);
+NPY_NO_EXPORT PyObject * PyArray_FromDims \
+ (int NPY_UNUSED(nd), int *NPY_UNUSED(d), int NPY_UNUSED(type));
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(3) PyObject * PyArray_FromDimsAndDataAndDescr \
+ (int NPY_UNUSED(nd), int *NPY_UNUSED(d), PyArray_Descr *, char *NPY_UNUSED(data));
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) PyObject * PyArray_FromAny \
+ (PyObject *, PyArray_Descr *, int, int, int, PyObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(1) PyObject * PyArray_EnsureArray \
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(1) PyObject * PyArray_EnsureAnyArray \
+NPY_NO_EXPORT PyObject * PyArray_FromFile \
+ (FILE *, PyArray_Descr *, npy_intp, char *);
+NPY_NO_EXPORT PyObject * PyArray_FromString \
+ (char *, npy_intp, PyArray_Descr *, npy_intp, char *);
+NPY_NO_EXPORT PyObject * PyArray_FromBuffer \
+ (PyObject *, PyArray_Descr *, npy_intp, npy_intp);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) PyObject * PyArray_FromIter \
+ (PyObject *, PyArray_Descr *, npy_intp);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(1) PyObject * PyArray_Return \
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) NPY_GCC_NONNULL(2) PyObject * PyArray_GetField \
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) NPY_GCC_NONNULL(2) int PyArray_SetField \
+ (PyArrayObject *, PyArray_Descr *, int, PyObject *);
+NPY_NO_EXPORT PyObject * PyArray_Byteswap \
+ (PyArrayObject *, npy_bool);
+NPY_NO_EXPORT PyObject * PyArray_Resize \
+ (PyArrayObject *, PyArray_Dims *, int, NPY_ORDER NPY_UNUSED(order));
+NPY_NO_EXPORT int PyArray_MoveInto \
+NPY_NO_EXPORT int PyArray_CopyInto \
+NPY_NO_EXPORT int PyArray_CopyAnyInto \
+NPY_NO_EXPORT int PyArray_CopyObject \
+ (PyArrayObject *, PyObject *);
+NPY_NO_EXPORT NPY_GCC_NONNULL(1) PyObject * PyArray_NewCopy \
+ (PyArrayObject *, NPY_ORDER);
+NPY_NO_EXPORT PyObject * PyArray_ToList \
+NPY_NO_EXPORT PyObject * PyArray_ToString \
+NPY_NO_EXPORT int PyArray_ToFile \
+ (PyArrayObject *, FILE *, char *, char *);
+NPY_NO_EXPORT int PyArray_Dump \
+ (PyObject *, PyObject *, int);
+NPY_NO_EXPORT PyObject * PyArray_Dumps \
+NPY_NO_EXPORT int PyArray_ValidType \
+NPY_NO_EXPORT void PyArray_UpdateFlags \
+ (PyArrayObject *, int);
+NPY_NO_EXPORT NPY_GCC_NONNULL(1) PyObject * PyArray_New \
+ (PyTypeObject *, int, npy_intp const *, int, npy_intp const *, void *, int, int, PyObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) NPY_GCC_NONNULL(1) NPY_GCC_NONNULL(2) PyObject * PyArray_NewFromDescr \
+ (PyTypeObject *, PyArray_Descr *, int, npy_intp const *, npy_intp const *, void *, int, PyObject *);
+NPY_NO_EXPORT PyArray_Descr * PyArray_DescrNew \
+ (PyArray_Descr *);
+NPY_NO_EXPORT PyArray_Descr * PyArray_DescrNewFromType \
+NPY_NO_EXPORT double PyArray_GetPriority \
+ (PyObject *, double);
+NPY_NO_EXPORT PyObject * PyArray_IterNew \
+NPY_NO_EXPORT PyObject* PyArray_MultiIterNew \
+ (int, ...);
+NPY_NO_EXPORT int PyArray_PyIntAsInt \
+NPY_NO_EXPORT npy_intp PyArray_PyIntAsIntp \
+NPY_NO_EXPORT int PyArray_Broadcast \
+ (PyArrayMultiIterObject *);
+NPY_NO_EXPORT void PyArray_FillObjectArray \
+NPY_NO_EXPORT int PyArray_FillWithScalar \
+NPY_NO_EXPORT npy_bool PyArray_CheckStrides \
+ (int, int, npy_intp, npy_intp, npy_intp const *, npy_intp const *);
+NPY_NO_EXPORT PyArray_Descr * PyArray_DescrNewByteorder \
+ (PyArray_Descr *, char);
+NPY_NO_EXPORT PyObject * PyArray_IterAllButAxis \
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) PyObject * PyArray_CheckFromAny \
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) PyObject * PyArray_FromArray \
+NPY_NO_EXPORT PyObject * PyArray_FromInterface \
+NPY_NO_EXPORT PyObject * PyArray_FromStructInterface \
+NPY_NO_EXPORT PyObject * PyArray_FromArrayAttr \
+ (PyObject *, PyArray_Descr *, PyObject *);
+NPY_NO_EXPORT NPY_SCALARKIND PyArray_ScalarKind \
+ (int, PyArrayObject **);
+NPY_NO_EXPORT int PyArray_CanCoerceScalar \
+ (int, int, NPY_SCALARKIND);
+NPY_NO_EXPORT PyObject * PyArray_NewFlagsObject \
+NPY_NO_EXPORT npy_bool PyArray_CanCastScalar \
+ (PyTypeObject *, PyTypeObject *);
+NPY_NO_EXPORT int PyArray_CompareUCS4 \
+ (npy_ucs4 const *, npy_ucs4 const *, size_t);
+NPY_NO_EXPORT int PyArray_RemoveSmallest \
+NPY_NO_EXPORT int PyArray_ElementStrides \
+NPY_NO_EXPORT void PyArray_Item_INCREF \
+ (char *, PyArray_Descr *);
+NPY_NO_EXPORT void PyArray_Item_XDECREF \
+NPY_NO_EXPORT PyObject * PyArray_FieldNames \
+NPY_NO_EXPORT PyObject * PyArray_Transpose \
+ (PyArrayObject *, PyArray_Dims *);
+NPY_NO_EXPORT PyObject * PyArray_TakeFrom \
+ (PyArrayObject *, PyObject *, int, PyArrayObject *, NPY_CLIPMODE);
+NPY_NO_EXPORT PyObject * PyArray_PutTo \
+ (PyArrayObject *, PyObject*, PyObject *, NPY_CLIPMODE);
+NPY_NO_EXPORT PyObject * PyArray_PutMask \
+ (PyArrayObject *, PyObject*, PyObject*);
+NPY_NO_EXPORT PyObject * PyArray_Repeat \
+ (PyArrayObject *, PyObject *, int);
+NPY_NO_EXPORT PyObject * PyArray_Choose \
+ (PyArrayObject *, PyObject *, PyArrayObject *, NPY_CLIPMODE);
+NPY_NO_EXPORT int PyArray_Sort \
+ (PyArrayObject *, int, NPY_SORTKIND);
+NPY_NO_EXPORT PyObject * PyArray_ArgSort \
+NPY_NO_EXPORT PyObject * PyArray_SearchSorted \
+ (PyArrayObject *, PyObject *, NPY_SEARCHSIDE, PyObject *);
+NPY_NO_EXPORT PyObject * PyArray_ArgMax \
+ (PyArrayObject *, int, PyArrayObject *);
+NPY_NO_EXPORT PyObject * PyArray_ArgMin \
+NPY_NO_EXPORT PyObject * PyArray_Reshape \
+NPY_NO_EXPORT PyObject * PyArray_Newshape \
+ (PyArrayObject *, PyArray_Dims *, NPY_ORDER);
+NPY_NO_EXPORT PyObject * PyArray_Squeeze \
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) PyObject * PyArray_View \
+ (PyArrayObject *, PyArray_Descr *, PyTypeObject *);
+NPY_NO_EXPORT PyObject * PyArray_SwapAxes \
+ (PyArrayObject *, int, int);
+NPY_NO_EXPORT PyObject * PyArray_Max \
+NPY_NO_EXPORT PyObject * PyArray_Min \
+NPY_NO_EXPORT PyObject * PyArray_Ptp \
+NPY_NO_EXPORT PyObject * PyArray_Mean \
+ (PyArrayObject *, int, int, PyArrayObject *);
+NPY_NO_EXPORT PyObject * PyArray_Trace \
+ (PyArrayObject *, int, int, int, int, PyArrayObject *);
+NPY_NO_EXPORT PyObject * PyArray_Diagonal \
+ (PyArrayObject *, int, int, int);
+NPY_NO_EXPORT PyObject * PyArray_Clip \
+ (PyArrayObject *, PyObject *, PyObject *, PyArrayObject *);
+NPY_NO_EXPORT PyObject * PyArray_Conjugate \
+NPY_NO_EXPORT PyObject * PyArray_Nonzero \
+NPY_NO_EXPORT PyObject * PyArray_Std \
+ (PyArrayObject *, int, int, PyArrayObject *, int);
+NPY_NO_EXPORT PyObject * PyArray_Sum \
+NPY_NO_EXPORT PyObject * PyArray_CumSum \
+NPY_NO_EXPORT PyObject * PyArray_Prod \
+NPY_NO_EXPORT PyObject * PyArray_CumProd \
+NPY_NO_EXPORT PyObject * PyArray_All \
+NPY_NO_EXPORT PyObject * PyArray_Any \
+NPY_NO_EXPORT PyObject * PyArray_Compress \
+ (PyArrayObject *, PyObject *, int, PyArrayObject *);
+NPY_NO_EXPORT PyObject * PyArray_Flatten \
+NPY_NO_EXPORT PyObject * PyArray_Ravel \
+NPY_NO_EXPORT npy_intp PyArray_MultiplyList \
+ (npy_intp const *, int);
+NPY_NO_EXPORT int PyArray_MultiplyIntList \
+ (int const *, int);
+NPY_NO_EXPORT void * PyArray_GetPtr \
+ (PyArrayObject *, npy_intp const*);
+NPY_NO_EXPORT int PyArray_CompareLists \
+ (npy_intp const *, npy_intp const *, int);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(5) int PyArray_AsCArray \
+ (PyObject **, void *, npy_intp *, int, PyArray_Descr*);
+NPY_NO_EXPORT int PyArray_As1D \
+ (PyObject **NPY_UNUSED(op), char **NPY_UNUSED(ptr), int *NPY_UNUSED(d1), int NPY_UNUSED(typecode));
+NPY_NO_EXPORT int PyArray_As2D \
+ (PyObject **NPY_UNUSED(op), char ***NPY_UNUSED(ptr), int *NPY_UNUSED(d1), int *NPY_UNUSED(d2), int NPY_UNUSED(typecode));
+NPY_NO_EXPORT int PyArray_Free \
+NPY_NO_EXPORT int PyArray_Converter \
+ (PyObject *, PyObject **);
+NPY_NO_EXPORT int PyArray_IntpFromSequence \
+ (PyObject *, npy_intp *, int);
+NPY_NO_EXPORT PyObject * PyArray_Concatenate \
+NPY_NO_EXPORT PyObject * PyArray_InnerProduct \
+ (PyObject *, PyObject *);
+NPY_NO_EXPORT PyObject * PyArray_MatrixProduct \
+NPY_NO_EXPORT PyObject * PyArray_CopyAndTranspose \
+NPY_NO_EXPORT PyObject * PyArray_Correlate \
+NPY_NO_EXPORT int PyArray_TypestrConvert \
+NPY_NO_EXPORT int PyArray_DescrConverter \
+ (PyObject *, PyArray_Descr **);
+NPY_NO_EXPORT int PyArray_DescrConverter2 \
+NPY_NO_EXPORT int PyArray_IntpConverter \
+ (PyObject *, PyArray_Dims *);
+NPY_NO_EXPORT int PyArray_BufferConverter \
+ (PyObject *, PyArray_Chunk *);
+NPY_NO_EXPORT int PyArray_AxisConverter \
+NPY_NO_EXPORT int PyArray_BoolConverter \
+ (PyObject *, npy_bool *);
+NPY_NO_EXPORT int PyArray_ByteorderConverter \
+ (PyObject *, char *);
+NPY_NO_EXPORT int PyArray_OrderConverter \
+ (PyObject *, NPY_ORDER *);
+NPY_NO_EXPORT unsigned char PyArray_EquivTypes \
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(3) PyObject * PyArray_Zeros \
+ (int, npy_intp const *, PyArray_Descr *, int);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(3) PyObject * PyArray_Empty \
+NPY_NO_EXPORT PyObject * PyArray_Where \
+ (PyObject *, PyObject *, PyObject *);
+NPY_NO_EXPORT PyObject * PyArray_Arange \
+ (double, double, double, int);
+NPY_NO_EXPORT PyObject * PyArray_ArangeObj \
+ (PyObject *, PyObject *, PyObject *, PyArray_Descr *);
+NPY_NO_EXPORT int PyArray_SortkindConverter \
+ (PyObject *, NPY_SORTKIND *);
+NPY_NO_EXPORT PyObject * PyArray_LexSort \
+NPY_NO_EXPORT PyObject * PyArray_Round \
+NPY_NO_EXPORT unsigned char PyArray_EquivTypenums \
+NPY_NO_EXPORT int PyArray_RegisterDataType \
+NPY_NO_EXPORT int PyArray_RegisterCastFunc \
+ (PyArray_Descr *, int, PyArray_VectorUnaryFunc *);
+NPY_NO_EXPORT int PyArray_RegisterCanCast \
+ (PyArray_Descr *, int, NPY_SCALARKIND);
+NPY_NO_EXPORT void PyArray_InitArrFuncs \
+ (PyArray_ArrFuncs *);
+NPY_NO_EXPORT PyObject * PyArray_IntTupleFromIntp \
+ (int, npy_intp const *);
+NPY_NO_EXPORT int PyArray_TypeNumFromName \
+ (char const *);
+NPY_NO_EXPORT int PyArray_ClipmodeConverter \
+ (PyObject *, NPY_CLIPMODE *);
+NPY_NO_EXPORT int PyArray_OutputConverter \
+ (PyObject *, PyArrayObject **);
+NPY_NO_EXPORT PyObject * PyArray_BroadcastToShape \
+NPY_NO_EXPORT void _PyArray_SigintHandler \
+NPY_NO_EXPORT void* _PyArray_GetSigintBuf \
+NPY_NO_EXPORT int PyArray_DescrAlignConverter \
+NPY_NO_EXPORT int PyArray_DescrAlignConverter2 \
+NPY_NO_EXPORT int PyArray_SearchsideConverter \
+NPY_NO_EXPORT PyObject * PyArray_CheckAxis \
+ (PyArrayObject *, int *, int);
+NPY_NO_EXPORT npy_intp PyArray_OverflowMultiplyList \
+NPY_NO_EXPORT int PyArray_CompareString \
+ (const char *, const char *, size_t);
+NPY_NO_EXPORT PyObject* PyArray_MultiIterFromObjects \
+ (PyObject **, int, int, ...);
+NPY_NO_EXPORT int PyArray_GetEndianness \
+NPY_NO_EXPORT unsigned int PyArray_GetNDArrayCFeatureVersion \
+NPY_NO_EXPORT PyObject * PyArray_Correlate2 \
+NPY_NO_EXPORT PyObject* PyArray_NeighborhoodIterNew \
+ (PyArrayIterObject *, const npy_intp *, int, PyArrayObject*);
+extern NPY_NO_EXPORT PyTypeObject PyTimeIntegerArrType_Type;
+extern NPY_NO_EXPORT PyTypeObject PyDatetimeArrType_Type;
+extern NPY_NO_EXPORT PyTypeObject PyTimedeltaArrType_Type;
+extern NPY_NO_EXPORT PyTypeObject PyHalfArrType_Type;
+extern NPY_NO_EXPORT PyTypeObject NpyIter_Type;
+NPY_NO_EXPORT void PyArray_SetDatetimeParseFunction \
+ (PyObject *NPY_UNUSED(op));
+NPY_NO_EXPORT void PyArray_DatetimeToDatetimeStruct \
+ (npy_datetime NPY_UNUSED(val), NPY_DATETIMEUNIT NPY_UNUSED(fr), npy_datetimestruct *);
+NPY_NO_EXPORT void PyArray_TimedeltaToTimedeltaStruct \
+ (npy_timedelta NPY_UNUSED(val), NPY_DATETIMEUNIT NPY_UNUSED(fr), npy_timedeltastruct *);
+NPY_NO_EXPORT npy_datetime PyArray_DatetimeStructToDatetime \
+ (NPY_DATETIMEUNIT NPY_UNUSED(fr), npy_datetimestruct *NPY_UNUSED(d));
+NPY_NO_EXPORT npy_datetime PyArray_TimedeltaStructToTimedelta \
+ (NPY_DATETIMEUNIT NPY_UNUSED(fr), npy_timedeltastruct *NPY_UNUSED(d));
+NPY_NO_EXPORT NpyIter * NpyIter_New \
+ (PyArrayObject *, npy_uint32, NPY_ORDER, NPY_CASTING, PyArray_Descr*);
+NPY_NO_EXPORT NpyIter * NpyIter_MultiNew \
+ (int, PyArrayObject **, npy_uint32, NPY_ORDER, NPY_CASTING, npy_uint32 *, PyArray_Descr **);
+NPY_NO_EXPORT NpyIter * NpyIter_AdvancedNew \
+ (int, PyArrayObject **, npy_uint32, NPY_ORDER, NPY_CASTING, npy_uint32 *, PyArray_Descr **, int, int **, npy_intp *, npy_intp);
+NPY_NO_EXPORT NpyIter * NpyIter_Copy \
+ (NpyIter *);
+NPY_NO_EXPORT int NpyIter_Deallocate \
+NPY_NO_EXPORT npy_bool NpyIter_HasDelayedBufAlloc \
+NPY_NO_EXPORT npy_bool NpyIter_HasExternalLoop \
+NPY_NO_EXPORT int NpyIter_EnableExternalLoop \
+NPY_NO_EXPORT npy_intp * NpyIter_GetInnerStrideArray \
+NPY_NO_EXPORT npy_intp * NpyIter_GetInnerLoopSizePtr \
+NPY_NO_EXPORT int NpyIter_Reset \
+ (NpyIter *, char **);
+NPY_NO_EXPORT int NpyIter_ResetBasePointers \
+ (NpyIter *, char **, char **);
+NPY_NO_EXPORT int NpyIter_ResetToIterIndexRange \
+ (NpyIter *, npy_intp, npy_intp, char **);
+NPY_NO_EXPORT int NpyIter_GetNDim \
+NPY_NO_EXPORT int NpyIter_GetNOp \
+NPY_NO_EXPORT NpyIter_IterNextFunc * NpyIter_GetIterNext \
+NPY_NO_EXPORT npy_intp NpyIter_GetIterSize \
+NPY_NO_EXPORT void NpyIter_GetIterIndexRange \
+ (NpyIter *, npy_intp *, npy_intp *);
+NPY_NO_EXPORT npy_intp NpyIter_GetIterIndex \
+NPY_NO_EXPORT int NpyIter_GotoIterIndex \
+ (NpyIter *, npy_intp);
+NPY_NO_EXPORT npy_bool NpyIter_HasMultiIndex \
+NPY_NO_EXPORT int NpyIter_GetShape \
+ (NpyIter *, npy_intp *);
+NPY_NO_EXPORT NpyIter_GetMultiIndexFunc * NpyIter_GetGetMultiIndex \
+NPY_NO_EXPORT int NpyIter_GotoMultiIndex \
+ (NpyIter *, npy_intp const *);
+NPY_NO_EXPORT int NpyIter_RemoveMultiIndex \
+NPY_NO_EXPORT npy_bool NpyIter_HasIndex \
+NPY_NO_EXPORT npy_bool NpyIter_IsBuffered \
+NPY_NO_EXPORT npy_bool NpyIter_IsGrowInner \
+NPY_NO_EXPORT npy_intp NpyIter_GetBufferSize \
+NPY_NO_EXPORT npy_intp * NpyIter_GetIndexPtr \
+NPY_NO_EXPORT int NpyIter_GotoIndex \
+NPY_NO_EXPORT char ** NpyIter_GetDataPtrArray \
+NPY_NO_EXPORT PyArray_Descr ** NpyIter_GetDescrArray \
+NPY_NO_EXPORT PyArrayObject ** NpyIter_GetOperandArray \
+NPY_NO_EXPORT PyArrayObject * NpyIter_GetIterView \
+NPY_NO_EXPORT void NpyIter_GetReadFlags \
+ (NpyIter *, char *);
+NPY_NO_EXPORT void NpyIter_GetWriteFlags \
+NPY_NO_EXPORT void NpyIter_DebugPrint \
+NPY_NO_EXPORT npy_bool NpyIter_IterationNeedsAPI \
+NPY_NO_EXPORT void NpyIter_GetInnerFixedStrideArray \
+NPY_NO_EXPORT int NpyIter_RemoveAxis \
+ (NpyIter *, int);
+NPY_NO_EXPORT npy_intp * NpyIter_GetAxisStrideArray \
+NPY_NO_EXPORT npy_bool NpyIter_RequiresBuffering \
+NPY_NO_EXPORT char ** NpyIter_GetInitialDataPtrArray \
+NPY_NO_EXPORT int NpyIter_CreateCompatibleStrides \
+ (NpyIter *, npy_intp, npy_intp *);
+NPY_NO_EXPORT int PyArray_CastingConverter \
+ (PyObject *, NPY_CASTING *);
+NPY_NO_EXPORT npy_intp PyArray_CountNonzero \
+NPY_NO_EXPORT PyArray_Descr * PyArray_PromoteTypes \
+NPY_NO_EXPORT PyArray_Descr * PyArray_MinScalarType \
+NPY_NO_EXPORT PyArray_Descr * PyArray_ResultType \
+ (npy_intp, PyArrayObject **, npy_intp, PyArray_Descr **);
+NPY_NO_EXPORT npy_bool PyArray_CanCastArrayTo \
+ (PyArrayObject *, PyArray_Descr *, NPY_CASTING);
+NPY_NO_EXPORT npy_bool PyArray_CanCastTypeTo \
+ (PyArray_Descr *, PyArray_Descr *, NPY_CASTING);
+NPY_NO_EXPORT PyArrayObject * PyArray_EinsteinSum \
+ (char *, npy_intp, PyArrayObject **, PyArray_Descr *, NPY_ORDER, NPY_CASTING, PyArrayObject *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(3) NPY_GCC_NONNULL(1) PyObject * PyArray_NewLikeArray \
+ (PyArrayObject *, NPY_ORDER, PyArray_Descr *, int);
+NPY_NO_EXPORT int PyArray_GetArrayParamsFromObject \
+ (PyObject *NPY_UNUSED(op), PyArray_Descr *NPY_UNUSED(requested_dtype), npy_bool NPY_UNUSED(writeable), PyArray_Descr **NPY_UNUSED(out_dtype), int *NPY_UNUSED(out_ndim), npy_intp *NPY_UNUSED(out_dims), PyArrayObject **NPY_UNUSED(out_arr), PyObject *NPY_UNUSED(context));
+NPY_NO_EXPORT int PyArray_ConvertClipmodeSequence \
+ (PyObject *, NPY_CLIPMODE *, int);
+NPY_NO_EXPORT PyObject * PyArray_MatrixProduct2 \
+ (PyObject *, PyObject *, PyArrayObject*);
+NPY_NO_EXPORT npy_bool NpyIter_IsFirstVisit \
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) int PyArray_SetBaseObject \
+NPY_NO_EXPORT void PyArray_CreateSortedStridePerm \
+ (int, npy_intp const *, npy_stride_sort_item *);
+NPY_NO_EXPORT void PyArray_RemoveAxesInPlace \
+ (PyArrayObject *, const npy_bool *);
+NPY_NO_EXPORT void PyArray_DebugPrint \
+NPY_NO_EXPORT int PyArray_FailUnlessWriteable \
+ (PyArrayObject *, const char *);
+NPY_NO_EXPORT NPY_STEALS_REF_TO_ARG(2) int PyArray_SetUpdateIfCopyBase \
+NPY_NO_EXPORT void * PyDataMem_NEW \
+ (size_t);
+NPY_NO_EXPORT void PyDataMem_FREE \
+ (void *);
+NPY_NO_EXPORT void * PyDataMem_RENEW \
+ (void *, size_t);
+NPY_NO_EXPORT PyDataMem_EventHookFunc * PyDataMem_SetEventHook \
+ (PyDataMem_EventHookFunc *, void *, void **);
+extern NPY_NO_EXPORT NPY_CASTING NPY_DEFAULT_ASSIGN_CASTING;
+NPY_NO_EXPORT void PyArray_MapIterSwapAxes \
+ (PyArrayMapIterObject *, PyArrayObject **, int);
+NPY_NO_EXPORT PyObject * PyArray_MapIterArray \
+NPY_NO_EXPORT void PyArray_MapIterNext \
+ (PyArrayMapIterObject *);
+NPY_NO_EXPORT int PyArray_Partition \
+ (PyArrayObject *, PyArrayObject *, int, NPY_SELECTKIND);
+NPY_NO_EXPORT PyObject * PyArray_ArgPartition \
+NPY_NO_EXPORT int PyArray_SelectkindConverter \
+ (PyObject *, NPY_SELECTKIND *);
+NPY_NO_EXPORT void * PyDataMem_NEW_ZEROED \
+ (size_t, size_t);
+NPY_NO_EXPORT NPY_GCC_NONNULL(1) int PyArray_CheckAnyScalarExact \
+NPY_NO_EXPORT PyObject * PyArray_MapIterArrayCopyIfOverlap \
+NPY_NO_EXPORT int PyArray_ResolveWritebackIfCopy \
+NPY_NO_EXPORT int PyArray_SetWritebackIfCopyBase \
+#define PyArray_GetNDArrayCVersion \
+ (*(unsigned int (*)(void)) \
+ PyArray_API[0])
+#define PyBigArray_Type (*(PyTypeObject *)PyArray_API[1])
+#define PyArray_Type (*(PyTypeObject *)PyArray_API[2])
+#define PyArrayDescr_Type (*(PyTypeObject *)PyArray_API[3])
+#define PyArrayFlags_Type (*(PyTypeObject *)PyArray_API[4])
+#define PyArrayIter_Type (*(PyTypeObject *)PyArray_API[5])
+#define PyArrayMultiIter_Type (*(PyTypeObject *)PyArray_API[6])
+#define NPY_NUMUSERTYPES (*(int *)PyArray_API[7])
+#define PyBoolArrType_Type (*(PyTypeObject *)PyArray_API[8])
+#define _PyArrayScalar_BoolValues ((PyBoolScalarObject *)PyArray_API[9])
+#define PyGenericArrType_Type (*(PyTypeObject *)PyArray_API[10])
+#define PyNumberArrType_Type (*(PyTypeObject *)PyArray_API[11])
+#define PyIntegerArrType_Type (*(PyTypeObject *)PyArray_API[12])
+#define PySignedIntegerArrType_Type (*(PyTypeObject *)PyArray_API[13])
+#define PyUnsignedIntegerArrType_Type (*(PyTypeObject *)PyArray_API[14])
+#define PyInexactArrType_Type (*(PyTypeObject *)PyArray_API[15])
+#define PyFloatingArrType_Type (*(PyTypeObject *)PyArray_API[16])
+#define PyComplexFloatingArrType_Type (*(PyTypeObject *)PyArray_API[17])
+#define PyFlexibleArrType_Type (*(PyTypeObject *)PyArray_API[18])
+#define PyCharacterArrType_Type (*(PyTypeObject *)PyArray_API[19])
+#define PyByteArrType_Type (*(PyTypeObject *)PyArray_API[20])
+#define PyShortArrType_Type (*(PyTypeObject *)PyArray_API[21])
+#define PyIntArrType_Type (*(PyTypeObject *)PyArray_API[22])
+#define PyLongArrType_Type (*(PyTypeObject *)PyArray_API[23])
+#define PyLongLongArrType_Type (*(PyTypeObject *)PyArray_API[24])
+#define PyUByteArrType_Type (*(PyTypeObject *)PyArray_API[25])
+#define PyUShortArrType_Type (*(PyTypeObject *)PyArray_API[26])
+#define PyUIntArrType_Type (*(PyTypeObject *)PyArray_API[27])
+#define PyULongArrType_Type (*(PyTypeObject *)PyArray_API[28])
+#define PyULongLongArrType_Type (*(PyTypeObject *)PyArray_API[29])
+#define PyFloatArrType_Type (*(PyTypeObject *)PyArray_API[30])
+#define PyDoubleArrType_Type (*(PyTypeObject *)PyArray_API[31])
+#define PyLongDoubleArrType_Type (*(PyTypeObject *)PyArray_API[32])
+#define PyCFloatArrType_Type (*(PyTypeObject *)PyArray_API[33])
+#define PyCDoubleArrType_Type (*(PyTypeObject *)PyArray_API[34])
+#define PyCLongDoubleArrType_Type (*(PyTypeObject *)PyArray_API[35])
+#define PyObjectArrType_Type (*(PyTypeObject *)PyArray_API[36])
+#define PyStringArrType_Type (*(PyTypeObject *)PyArray_API[37])
+#define PyUnicodeArrType_Type (*(PyTypeObject *)PyArray_API[38])
+#define PyVoidArrType_Type (*(PyTypeObject *)PyArray_API[39])
+#define PyArray_SetNumericOps \
+ (*(int (*)(PyObject *)) \
+ PyArray_API[40])
+#define PyArray_GetNumericOps \
+ (*(PyObject * (*)(void)) \
+ PyArray_API[41])
+#define PyArray_INCREF \
+ (*(int (*)(PyArrayObject *)) \
+ PyArray_API[42])
+#define PyArray_XDECREF \
+ PyArray_API[43])
+#define PyArray_SetStringFunction \
+ (*(void (*)(PyObject *, int)) \
+ PyArray_API[44])
+#define PyArray_DescrFromType \
+ (*(PyArray_Descr * (*)(int)) \
+ PyArray_API[45])
+#define PyArray_TypeObjectFromType \
+ (*(PyObject * (*)(int)) \
+ PyArray_API[46])
+#define PyArray_Zero \
+ (*(char * (*)(PyArrayObject *)) \
+ PyArray_API[47])
+#define PyArray_One \
+ PyArray_API[48])
+#define PyArray_CastToType \
+ (*(PyObject * (*)(PyArrayObject *, PyArray_Descr *, int)) \
+ PyArray_API[49])
+#define PyArray_CastTo \
+ (*(int (*)(PyArrayObject *, PyArrayObject *)) \
+ PyArray_API[50])
+#define PyArray_CastAnyTo \
+ PyArray_API[51])
+#define PyArray_CanCastSafely \
+ (*(int (*)(int, int)) \
+ PyArray_API[52])
+#define PyArray_CanCastTo \
+ (*(npy_bool (*)(PyArray_Descr *, PyArray_Descr *)) \
+ PyArray_API[53])
+#define PyArray_ObjectType \
+ (*(int (*)(PyObject *, int)) \
+ PyArray_API[54])
+#define PyArray_DescrFromObject \
+ (*(PyArray_Descr * (*)(PyObject *, PyArray_Descr *)) \
+ PyArray_API[55])
+#define PyArray_ConvertToCommonType \
+ (*(PyArrayObject ** (*)(PyObject *, int *)) \
+ PyArray_API[56])
+#define PyArray_DescrFromScalar \
+ (*(PyArray_Descr * (*)(PyObject *)) \
+ PyArray_API[57])
+#define PyArray_DescrFromTypeObject \
+ PyArray_API[58])
+#define PyArray_Size \
+ (*(npy_intp (*)(PyObject *)) \
+ PyArray_API[59])
+#define PyArray_Scalar \
+ (*(PyObject * (*)(void *, PyArray_Descr *, PyObject *)) \
+ PyArray_API[60])
+#define PyArray_FromScalar \
+ (*(PyObject * (*)(PyObject *, PyArray_Descr *)) \
+ PyArray_API[61])
+#define PyArray_ScalarAsCtype \
+ (*(void (*)(PyObject *, void *)) \
+ PyArray_API[62])
+#define PyArray_CastScalarToCtype \
+ (*(int (*)(PyObject *, void *, PyArray_Descr *)) \
+ PyArray_API[63])
+#define PyArray_CastScalarDirect \
+ (*(int (*)(PyObject *, PyArray_Descr *, void *, int)) \
+ PyArray_API[64])
+#define PyArray_ScalarFromObject \
+ (*(PyObject * (*)(PyObject *)) \
+ PyArray_API[65])
+#define PyArray_GetCastFunc \
+ (*(PyArray_VectorUnaryFunc * (*)(PyArray_Descr *, int)) \
+ PyArray_API[66])
+#define PyArray_FromDims \
+ (*(PyObject * (*)(int NPY_UNUSED(nd), int *NPY_UNUSED(d), int NPY_UNUSED(type))) \
+ PyArray_API[67])
+#define PyArray_FromDimsAndDataAndDescr \
+ (*(PyObject * (*)(int NPY_UNUSED(nd), int *NPY_UNUSED(d), PyArray_Descr *, char *NPY_UNUSED(data))) \
+ PyArray_API[68])
+#define PyArray_FromAny \
+ (*(PyObject * (*)(PyObject *, PyArray_Descr *, int, int, int, PyObject *)) \
+ PyArray_API[69])
+#define PyArray_EnsureArray \
+ PyArray_API[70])
+#define PyArray_EnsureAnyArray \
+ PyArray_API[71])
+#define PyArray_FromFile \
+ (*(PyObject * (*)(FILE *, PyArray_Descr *, npy_intp, char *)) \
+ PyArray_API[72])
+#define PyArray_FromString \
+ (*(PyObject * (*)(char *, npy_intp, PyArray_Descr *, npy_intp, char *)) \
+ PyArray_API[73])
+#define PyArray_FromBuffer \
+ (*(PyObject * (*)(PyObject *, PyArray_Descr *, npy_intp, npy_intp)) \
+ PyArray_API[74])
+#define PyArray_FromIter \
+ (*(PyObject * (*)(PyObject *, PyArray_Descr *, npy_intp)) \
+ PyArray_API[75])
+#define PyArray_Return \
+ (*(PyObject * (*)(PyArrayObject *)) \
+ PyArray_API[76])
+#define PyArray_GetField \
+ PyArray_API[77])
+#define PyArray_SetField \
+ (*(int (*)(PyArrayObject *, PyArray_Descr *, int, PyObject *)) \
+ PyArray_API[78])
+#define PyArray_Byteswap \
+ (*(PyObject * (*)(PyArrayObject *, npy_bool)) \
+ PyArray_API[79])
+#define PyArray_Resize \
+ (*(PyObject * (*)(PyArrayObject *, PyArray_Dims *, int, NPY_ORDER NPY_UNUSED(order))) \
+ PyArray_API[80])
+#define PyArray_MoveInto \
+ PyArray_API[81])
+#define PyArray_CopyInto \
+ PyArray_API[82])
+#define PyArray_CopyAnyInto \
+ PyArray_API[83])
+#define PyArray_CopyObject \
+ (*(int (*)(PyArrayObject *, PyObject *)) \
+ PyArray_API[84])
+#define PyArray_NewCopy \
+ (*(PyObject * (*)(PyArrayObject *, NPY_ORDER)) \
+ PyArray_API[85])
+#define PyArray_ToList \
+ PyArray_API[86])
+#define PyArray_ToString \
+ PyArray_API[87])
+#define PyArray_ToFile \
+ (*(int (*)(PyArrayObject *, FILE *, char *, char *)) \
+ PyArray_API[88])
+#define PyArray_Dump \
+ (*(int (*)(PyObject *, PyObject *, int)) \
+ PyArray_API[89])
+#define PyArray_Dumps \
+ (*(PyObject * (*)(PyObject *, int)) \
+ PyArray_API[90])
+#define PyArray_ValidType \
+ (*(int (*)(int)) \
+ PyArray_API[91])
+#define PyArray_UpdateFlags \
+ (*(void (*)(PyArrayObject *, int)) \
+ PyArray_API[92])
+#define PyArray_New \
+ (*(PyObject * (*)(PyTypeObject *, int, npy_intp const *, int, npy_intp const *, void *, int, int, PyObject *)) \
+ PyArray_API[93])
+#define PyArray_NewFromDescr \
+ (*(PyObject * (*)(PyTypeObject *, PyArray_Descr *, int, npy_intp const *, npy_intp const *, void *, int, PyObject *)) \
+ PyArray_API[94])
+#define PyArray_DescrNew \
+ (*(PyArray_Descr * (*)(PyArray_Descr *)) \
+ PyArray_API[95])
+#define PyArray_DescrNewFromType \
+ PyArray_API[96])
+#define PyArray_GetPriority \
+ (*(double (*)(PyObject *, double)) \
+ PyArray_API[97])
+#define PyArray_IterNew \
+ PyArray_API[98])
+#define PyArray_MultiIterNew \
+ (*(PyObject* (*)(int, ...)) \
+ PyArray_API[99])
+#define PyArray_PyIntAsInt \
+ PyArray_API[100])
+#define PyArray_PyIntAsIntp \
+ PyArray_API[101])
+#define PyArray_Broadcast \
+ (*(int (*)(PyArrayMultiIterObject *)) \
+ PyArray_API[102])
+#define PyArray_FillObjectArray \
+ (*(void (*)(PyArrayObject *, PyObject *)) \
+ PyArray_API[103])
+#define PyArray_FillWithScalar \
+ PyArray_API[104])
+#define PyArray_CheckStrides \
+ (*(npy_bool (*)(int, int, npy_intp, npy_intp, npy_intp const *, npy_intp const *)) \
+ PyArray_API[105])
+#define PyArray_DescrNewByteorder \
+ (*(PyArray_Descr * (*)(PyArray_Descr *, char)) \
+ PyArray_API[106])
+#define PyArray_IterAllButAxis \
+ (*(PyObject * (*)(PyObject *, int *)) \
+ PyArray_API[107])
+#define PyArray_CheckFromAny \
+ PyArray_API[108])
+#define PyArray_FromArray \
+ PyArray_API[109])
+#define PyArray_FromInterface \
+ PyArray_API[110])
+#define PyArray_FromStructInterface \
+ PyArray_API[111])
+#define PyArray_FromArrayAttr \
+ (*(PyObject * (*)(PyObject *, PyArray_Descr *, PyObject *)) \
+ PyArray_API[112])
+#define PyArray_ScalarKind \
+ (*(NPY_SCALARKIND (*)(int, PyArrayObject **)) \
+ PyArray_API[113])
+#define PyArray_CanCoerceScalar \
+ (*(int (*)(int, int, NPY_SCALARKIND)) \
+ PyArray_API[114])
+#define PyArray_NewFlagsObject \
+ PyArray_API[115])
+#define PyArray_CanCastScalar \
+ (*(npy_bool (*)(PyTypeObject *, PyTypeObject *)) \
+ PyArray_API[116])
+#define PyArray_CompareUCS4 \
+ (*(int (*)(npy_ucs4 const *, npy_ucs4 const *, size_t)) \
+ PyArray_API[117])
+#define PyArray_RemoveSmallest \
+ PyArray_API[118])
+#define PyArray_ElementStrides \
+ PyArray_API[119])
+#define PyArray_Item_INCREF \
+ (*(void (*)(char *, PyArray_Descr *)) \
+ PyArray_API[120])
+#define PyArray_Item_XDECREF \
+ PyArray_API[121])
+#define PyArray_FieldNames \
+ PyArray_API[122])
+#define PyArray_Transpose \
+ (*(PyObject * (*)(PyArrayObject *, PyArray_Dims *)) \
+ PyArray_API[123])
+#define PyArray_TakeFrom \
+ (*(PyObject * (*)(PyArrayObject *, PyObject *, int, PyArrayObject *, NPY_CLIPMODE)) \
+ PyArray_API[124])
+#define PyArray_PutTo \
+ (*(PyObject * (*)(PyArrayObject *, PyObject*, PyObject *, NPY_CLIPMODE)) \
+ PyArray_API[125])
+#define PyArray_PutMask \
+ (*(PyObject * (*)(PyArrayObject *, PyObject*, PyObject*)) \
+ PyArray_API[126])
+#define PyArray_Repeat \
+ (*(PyObject * (*)(PyArrayObject *, PyObject *, int)) \
+ PyArray_API[127])
+#define PyArray_Choose \
+ (*(PyObject * (*)(PyArrayObject *, PyObject *, PyArrayObject *, NPY_CLIPMODE)) \
+ PyArray_API[128])
+#define PyArray_Sort \
+ (*(int (*)(PyArrayObject *, int, NPY_SORTKIND)) \
+ PyArray_API[129])
+#define PyArray_ArgSort \
+ (*(PyObject * (*)(PyArrayObject *, int, NPY_SORTKIND)) \
+ PyArray_API[130])
+#define PyArray_SearchSorted \
+ (*(PyObject * (*)(PyArrayObject *, PyObject *, NPY_SEARCHSIDE, PyObject *)) \
+ PyArray_API[131])
+#define PyArray_ArgMax \
+ (*(PyObject * (*)(PyArrayObject *, int, PyArrayObject *)) \
+ PyArray_API[132])
+#define PyArray_ArgMin \
+ PyArray_API[133])
+#define PyArray_Reshape \
+ (*(PyObject * (*)(PyArrayObject *, PyObject *)) \
+ PyArray_API[134])
+#define PyArray_Newshape \
+ (*(PyObject * (*)(PyArrayObject *, PyArray_Dims *, NPY_ORDER)) \
+ PyArray_API[135])
+#define PyArray_Squeeze \
+ PyArray_API[136])
+#define PyArray_View \
+ (*(PyObject * (*)(PyArrayObject *, PyArray_Descr *, PyTypeObject *)) \
+ PyArray_API[137])
+#define PyArray_SwapAxes \
+ (*(PyObject * (*)(PyArrayObject *, int, int)) \
+ PyArray_API[138])
+#define PyArray_Max \
+ PyArray_API[139])
+#define PyArray_Min \
+ PyArray_API[140])
+#define PyArray_Ptp \
+ PyArray_API[141])
+#define PyArray_Mean \
+ (*(PyObject * (*)(PyArrayObject *, int, int, PyArrayObject *)) \
+ PyArray_API[142])
+#define PyArray_Trace \
+ (*(PyObject * (*)(PyArrayObject *, int, int, int, int, PyArrayObject *)) \
+ PyArray_API[143])
+#define PyArray_Diagonal \
+ (*(PyObject * (*)(PyArrayObject *, int, int, int)) \
+ PyArray_API[144])
+#define PyArray_Clip \
+ (*(PyObject * (*)(PyArrayObject *, PyObject *, PyObject *, PyArrayObject *)) \
+ PyArray_API[145])
+#define PyArray_Conjugate \
+ (*(PyObject * (*)(PyArrayObject *, PyArrayObject *)) \
+ PyArray_API[146])
+#define PyArray_Nonzero \
+ PyArray_API[147])
+#define PyArray_Std \
+ (*(PyObject * (*)(PyArrayObject *, int, int, PyArrayObject *, int)) \
+ PyArray_API[148])
+#define PyArray_Sum \
+ PyArray_API[149])
+#define PyArray_CumSum \
+ PyArray_API[150])
+#define PyArray_Prod \
+ PyArray_API[151])
+#define PyArray_CumProd \
+ PyArray_API[152])
+#define PyArray_All \
+ PyArray_API[153])
+#define PyArray_Any \
+ PyArray_API[154])
+#define PyArray_Compress \
+ (*(PyObject * (*)(PyArrayObject *, PyObject *, int, PyArrayObject *)) \
+ PyArray_API[155])
+#define PyArray_Flatten \
+ PyArray_API[156])
+#define PyArray_Ravel \
+ PyArray_API[157])
+#define PyArray_MultiplyList \
+ (*(npy_intp (*)(npy_intp const *, int)) \
+ PyArray_API[158])
+#define PyArray_MultiplyIntList \
+ (*(int (*)(int const *, int)) \
+ PyArray_API[159])
+#define PyArray_GetPtr \
+ (*(void * (*)(PyArrayObject *, npy_intp const*)) \
+ PyArray_API[160])
+#define PyArray_CompareLists \
+ (*(int (*)(npy_intp const *, npy_intp const *, int)) \
+ PyArray_API[161])
+#define PyArray_AsCArray \
+ (*(int (*)(PyObject **, void *, npy_intp *, int, PyArray_Descr*)) \
+ PyArray_API[162])
+#define PyArray_As1D \
+ (*(int (*)(PyObject **NPY_UNUSED(op), char **NPY_UNUSED(ptr), int *NPY_UNUSED(d1), int NPY_UNUSED(typecode))) \
+ PyArray_API[163])
+#define PyArray_As2D \
+ (*(int (*)(PyObject **NPY_UNUSED(op), char ***NPY_UNUSED(ptr), int *NPY_UNUSED(d1), int *NPY_UNUSED(d2), int NPY_UNUSED(typecode))) \
+ PyArray_API[164])
+#define PyArray_Free \
+ (*(int (*)(PyObject *, void *)) \
+ PyArray_API[165])
+#define PyArray_Converter \
+ (*(int (*)(PyObject *, PyObject **)) \
+ PyArray_API[166])
+#define PyArray_IntpFromSequence \
+ (*(int (*)(PyObject *, npy_intp *, int)) \
+ PyArray_API[167])
+#define PyArray_Concatenate \
+ PyArray_API[168])
+#define PyArray_InnerProduct \
+ (*(PyObject * (*)(PyObject *, PyObject *)) \
+ PyArray_API[169])
+#define PyArray_MatrixProduct \
+ PyArray_API[170])
+#define PyArray_CopyAndTranspose \
+ PyArray_API[171])
+#define PyArray_Correlate \
+ (*(PyObject * (*)(PyObject *, PyObject *, int)) \
+ PyArray_API[172])
+#define PyArray_TypestrConvert \
+ PyArray_API[173])
+#define PyArray_DescrConverter \
+ (*(int (*)(PyObject *, PyArray_Descr **)) \
+ PyArray_API[174])
+#define PyArray_DescrConverter2 \
+ PyArray_API[175])
+#define PyArray_IntpConverter \
+ (*(int (*)(PyObject *, PyArray_Dims *)) \
+ PyArray_API[176])
+#define PyArray_BufferConverter \
+ (*(int (*)(PyObject *, PyArray_Chunk *)) \
+ PyArray_API[177])
+#define PyArray_AxisConverter \
+ (*(int (*)(PyObject *, int *)) \
+ PyArray_API[178])
+#define PyArray_BoolConverter \
+ (*(int (*)(PyObject *, npy_bool *)) \
+ PyArray_API[179])
+#define PyArray_ByteorderConverter \
+ (*(int (*)(PyObject *, char *)) \
+ PyArray_API[180])
+#define PyArray_OrderConverter \
+ (*(int (*)(PyObject *, NPY_ORDER *)) \
+ PyArray_API[181])
+#define PyArray_EquivTypes \
+ (*(unsigned char (*)(PyArray_Descr *, PyArray_Descr *)) \
+ PyArray_API[182])
+#define PyArray_Zeros \
+ (*(PyObject * (*)(int, npy_intp const *, PyArray_Descr *, int)) \
+ PyArray_API[183])
+#define PyArray_Empty \
+ PyArray_API[184])
+#define PyArray_Where \
+ (*(PyObject * (*)(PyObject *, PyObject *, PyObject *)) \
+ PyArray_API[185])
+#define PyArray_Arange \
+ (*(PyObject * (*)(double, double, double, int)) \
+ PyArray_API[186])
+#define PyArray_ArangeObj \
+ (*(PyObject * (*)(PyObject *, PyObject *, PyObject *, PyArray_Descr *)) \
+ PyArray_API[187])
+#define PyArray_SortkindConverter \
+ (*(int (*)(PyObject *, NPY_SORTKIND *)) \
+ PyArray_API[188])
+#define PyArray_LexSort \
+ PyArray_API[189])
+#define PyArray_Round \
+ PyArray_API[190])
+#define PyArray_EquivTypenums \
+ (*(unsigned char (*)(int, int)) \
+ PyArray_API[191])
+#define PyArray_RegisterDataType \
+ (*(int (*)(PyArray_Descr *)) \
+ PyArray_API[192])
+#define PyArray_RegisterCastFunc \
+ (*(int (*)(PyArray_Descr *, int, PyArray_VectorUnaryFunc *)) \
+ PyArray_API[193])
+#define PyArray_RegisterCanCast \
+ (*(int (*)(PyArray_Descr *, int, NPY_SCALARKIND)) \
+ PyArray_API[194])
+#define PyArray_InitArrFuncs \
+ (*(void (*)(PyArray_ArrFuncs *)) \
+ PyArray_API[195])
+#define PyArray_IntTupleFromIntp \
+ (*(PyObject * (*)(int, npy_intp const *)) \
+ PyArray_API[196])
+#define PyArray_TypeNumFromName \
+ (*(int (*)(char const *)) \
+ PyArray_API[197])
+#define PyArray_ClipmodeConverter \
+ (*(int (*)(PyObject *, NPY_CLIPMODE *)) \
+ PyArray_API[198])
+#define PyArray_OutputConverter \
+ (*(int (*)(PyObject *, PyArrayObject **)) \
+ PyArray_API[199])
+#define PyArray_BroadcastToShape \
+ (*(PyObject * (*)(PyObject *, npy_intp *, int)) \
+ PyArray_API[200])
+#define _PyArray_SigintHandler \
+ (*(void (*)(int)) \
+ PyArray_API[201])
+#define _PyArray_GetSigintBuf \
+ (*(void* (*)(void)) \
+ PyArray_API[202])
+#define PyArray_DescrAlignConverter \
+ PyArray_API[203])
+#define PyArray_DescrAlignConverter2 \
+ PyArray_API[204])
+#define PyArray_SearchsideConverter \
+ PyArray_API[205])
+#define PyArray_CheckAxis \
+ (*(PyObject * (*)(PyArrayObject *, int *, int)) \
+ PyArray_API[206])
+#define PyArray_OverflowMultiplyList \
+ PyArray_API[207])
+#define PyArray_CompareString \
+ (*(int (*)(const char *, const char *, size_t)) \
+ PyArray_API[208])
+#define PyArray_MultiIterFromObjects \
+ (*(PyObject* (*)(PyObject **, int, int, ...)) \
+ PyArray_API[209])
+#define PyArray_GetEndianness \
+ (*(int (*)(void)) \
+ PyArray_API[210])
+#define PyArray_GetNDArrayCFeatureVersion \
+ PyArray_API[211])
+#define PyArray_Correlate2 \
+ PyArray_API[212])
+#define PyArray_NeighborhoodIterNew \
+ (*(PyObject* (*)(PyArrayIterObject *, const npy_intp *, int, PyArrayObject*)) \
+ PyArray_API[213])
+#define PyTimeIntegerArrType_Type (*(PyTypeObject *)PyArray_API[214])
+#define PyDatetimeArrType_Type (*(PyTypeObject *)PyArray_API[215])
+#define PyTimedeltaArrType_Type (*(PyTypeObject *)PyArray_API[216])
+#define PyHalfArrType_Type (*(PyTypeObject *)PyArray_API[217])
+#define NpyIter_Type (*(PyTypeObject *)PyArray_API[218])
+#define PyArray_SetDatetimeParseFunction \
+ (*(void (*)(PyObject *NPY_UNUSED(op))) \
+ PyArray_API[219])
+#define PyArray_DatetimeToDatetimeStruct \
+ (*(void (*)(npy_datetime NPY_UNUSED(val), NPY_DATETIMEUNIT NPY_UNUSED(fr), npy_datetimestruct *)) \
+ PyArray_API[220])
+#define PyArray_TimedeltaToTimedeltaStruct \
+ (*(void (*)(npy_timedelta NPY_UNUSED(val), NPY_DATETIMEUNIT NPY_UNUSED(fr), npy_timedeltastruct *)) \
+ PyArray_API[221])
+#define PyArray_DatetimeStructToDatetime \
+ (*(npy_datetime (*)(NPY_DATETIMEUNIT NPY_UNUSED(fr), npy_datetimestruct *NPY_UNUSED(d))) \
+ PyArray_API[222])
+#define PyArray_TimedeltaStructToTimedelta \
+ (*(npy_datetime (*)(NPY_DATETIMEUNIT NPY_UNUSED(fr), npy_timedeltastruct *NPY_UNUSED(d))) \
+ PyArray_API[223])
+#define NpyIter_New \
+ (*(NpyIter * (*)(PyArrayObject *, npy_uint32, NPY_ORDER, NPY_CASTING, PyArray_Descr*)) \
+ PyArray_API[224])
+#define NpyIter_MultiNew \
+ (*(NpyIter * (*)(int, PyArrayObject **, npy_uint32, NPY_ORDER, NPY_CASTING, npy_uint32 *, PyArray_Descr **)) \
+ PyArray_API[225])
+#define NpyIter_AdvancedNew \
+ (*(NpyIter * (*)(int, PyArrayObject **, npy_uint32, NPY_ORDER, NPY_CASTING, npy_uint32 *, PyArray_Descr **, int, int **, npy_intp *, npy_intp)) \
+ PyArray_API[226])
+#define NpyIter_Copy \
+ (*(NpyIter * (*)(NpyIter *)) \
+ PyArray_API[227])
+#define NpyIter_Deallocate \
+ (*(int (*)(NpyIter *)) \
+ PyArray_API[228])
+#define NpyIter_HasDelayedBufAlloc \
+ (*(npy_bool (*)(NpyIter *)) \
+ PyArray_API[229])
+#define NpyIter_HasExternalLoop \
+ PyArray_API[230])
+#define NpyIter_EnableExternalLoop \
+ PyArray_API[231])
+#define NpyIter_GetInnerStrideArray \
+ (*(npy_intp * (*)(NpyIter *)) \
+ PyArray_API[232])
+#define NpyIter_GetInnerLoopSizePtr \
+ PyArray_API[233])
+#define NpyIter_Reset \
+ (*(int (*)(NpyIter *, char **)) \
+ PyArray_API[234])
+#define NpyIter_ResetBasePointers \
+ (*(int (*)(NpyIter *, char **, char **)) \
+ PyArray_API[235])
+#define NpyIter_ResetToIterIndexRange \
+ (*(int (*)(NpyIter *, npy_intp, npy_intp, char **)) \
+ PyArray_API[236])
+#define NpyIter_GetNDim \
+ PyArray_API[237])
+#define NpyIter_GetNOp \
+ PyArray_API[238])
+#define NpyIter_GetIterNext \
+ (*(NpyIter_IterNextFunc * (*)(NpyIter *, char **)) \
+ PyArray_API[239])
+#define NpyIter_GetIterSize \
+ (*(npy_intp (*)(NpyIter *)) \
+ PyArray_API[240])
+#define NpyIter_GetIterIndexRange \
+ (*(void (*)(NpyIter *, npy_intp *, npy_intp *)) \
+ PyArray_API[241])
+#define NpyIter_GetIterIndex \
+ PyArray_API[242])
+#define NpyIter_GotoIterIndex \
+ (*(int (*)(NpyIter *, npy_intp)) \
+ PyArray_API[243])
+#define NpyIter_HasMultiIndex \
+ PyArray_API[244])
+#define NpyIter_GetShape \
+ (*(int (*)(NpyIter *, npy_intp *)) \
+ PyArray_API[245])
+#define NpyIter_GetGetMultiIndex \
+ (*(NpyIter_GetMultiIndexFunc * (*)(NpyIter *, char **)) \
+ PyArray_API[246])
+#define NpyIter_GotoMultiIndex \
+ (*(int (*)(NpyIter *, npy_intp const *)) \
+ PyArray_API[247])
+#define NpyIter_RemoveMultiIndex \
+ PyArray_API[248])
+#define NpyIter_HasIndex \
+ PyArray_API[249])
+#define NpyIter_IsBuffered \
+ PyArray_API[250])
+#define NpyIter_IsGrowInner \
+ PyArray_API[251])
+#define NpyIter_GetBufferSize \
+ PyArray_API[252])
+#define NpyIter_GetIndexPtr \
+ PyArray_API[253])
+#define NpyIter_GotoIndex \
+ PyArray_API[254])
+#define NpyIter_GetDataPtrArray \
+ (*(char ** (*)(NpyIter *)) \
+ PyArray_API[255])
+#define NpyIter_GetDescrArray \
+ (*(PyArray_Descr ** (*)(NpyIter *)) \
+ PyArray_API[256])
+#define NpyIter_GetOperandArray \
+ (*(PyArrayObject ** (*)(NpyIter *)) \
+ PyArray_API[257])
+#define NpyIter_GetIterView \
+ (*(PyArrayObject * (*)(NpyIter *, npy_intp)) \
+ PyArray_API[258])
+#define NpyIter_GetReadFlags \
+ (*(void (*)(NpyIter *, char *)) \
+ PyArray_API[259])
+#define NpyIter_GetWriteFlags \
+ PyArray_API[260])
+#define NpyIter_DebugPrint \
+ (*(void (*)(NpyIter *)) \
+ PyArray_API[261])
+#define NpyIter_IterationNeedsAPI \
+ PyArray_API[262])
+#define NpyIter_GetInnerFixedStrideArray \
+ (*(void (*)(NpyIter *, npy_intp *)) \
+ PyArray_API[263])
+#define NpyIter_RemoveAxis \
+ (*(int (*)(NpyIter *, int)) \
+ PyArray_API[264])
+#define NpyIter_GetAxisStrideArray \
+ (*(npy_intp * (*)(NpyIter *, int)) \
+ PyArray_API[265])
+#define NpyIter_RequiresBuffering \
+ PyArray_API[266])
+#define NpyIter_GetInitialDataPtrArray \
+ PyArray_API[267])
+#define NpyIter_CreateCompatibleStrides \
+ (*(int (*)(NpyIter *, npy_intp, npy_intp *)) \
+ PyArray_API[268])
+#define PyArray_CastingConverter \
+ (*(int (*)(PyObject *, NPY_CASTING *)) \
+ PyArray_API[269])
+#define PyArray_CountNonzero \
+ (*(npy_intp (*)(PyArrayObject *)) \
+ PyArray_API[270])
+#define PyArray_PromoteTypes \
+ (*(PyArray_Descr * (*)(PyArray_Descr *, PyArray_Descr *)) \
+ PyArray_API[271])
+#define PyArray_MinScalarType \
+ (*(PyArray_Descr * (*)(PyArrayObject *)) \
+ PyArray_API[272])
+#define PyArray_ResultType \
+ (*(PyArray_Descr * (*)(npy_intp, PyArrayObject **, npy_intp, PyArray_Descr **)) \
+ PyArray_API[273])
+#define PyArray_CanCastArrayTo \
+ (*(npy_bool (*)(PyArrayObject *, PyArray_Descr *, NPY_CASTING)) \
+ PyArray_API[274])
+#define PyArray_CanCastTypeTo \
+ (*(npy_bool (*)(PyArray_Descr *, PyArray_Descr *, NPY_CASTING)) \
+ PyArray_API[275])
+#define PyArray_EinsteinSum \
+ (*(PyArrayObject * (*)(char *, npy_intp, PyArrayObject **, PyArray_Descr *, NPY_ORDER, NPY_CASTING, PyArrayObject *)) \
+ PyArray_API[276])
+#define PyArray_NewLikeArray \
+ (*(PyObject * (*)(PyArrayObject *, NPY_ORDER, PyArray_Descr *, int)) \
+ PyArray_API[277])
+#define PyArray_GetArrayParamsFromObject \
+ (*(int (*)(PyObject *NPY_UNUSED(op), PyArray_Descr *NPY_UNUSED(requested_dtype), npy_bool NPY_UNUSED(writeable), PyArray_Descr **NPY_UNUSED(out_dtype), int *NPY_UNUSED(out_ndim), npy_intp *NPY_UNUSED(out_dims), PyArrayObject **NPY_UNUSED(out_arr), PyObject *NPY_UNUSED(context))) \
+ PyArray_API[278])
+#define PyArray_ConvertClipmodeSequence \
+ (*(int (*)(PyObject *, NPY_CLIPMODE *, int)) \
+ PyArray_API[279])
+#define PyArray_MatrixProduct2 \
+ (*(PyObject * (*)(PyObject *, PyObject *, PyArrayObject*)) \
+ PyArray_API[280])
+#define NpyIter_IsFirstVisit \
+ (*(npy_bool (*)(NpyIter *, int)) \
+ PyArray_API[281])
+#define PyArray_SetBaseObject \
+ PyArray_API[282])
+#define PyArray_CreateSortedStridePerm \
+ (*(void (*)(int, npy_intp const *, npy_stride_sort_item *)) \
+ PyArray_API[283])
+#define PyArray_RemoveAxesInPlace \
+ (*(void (*)(PyArrayObject *, const npy_bool *)) \
+ PyArray_API[284])
+#define PyArray_DebugPrint \
+ (*(void (*)(PyArrayObject *)) \
+ PyArray_API[285])
+#define PyArray_FailUnlessWriteable \
+ (*(int (*)(PyArrayObject *, const char *)) \
+ PyArray_API[286])
+#define PyArray_SetUpdateIfCopyBase \
+ PyArray_API[287])
+#define PyDataMem_NEW \
+ (*(void * (*)(size_t)) \
+ PyArray_API[288])
+#define PyDataMem_FREE \
+ (*(void (*)(void *)) \
+ PyArray_API[289])
+#define PyDataMem_RENEW \
+ (*(void * (*)(void *, size_t)) \
+ PyArray_API[290])
+#define PyDataMem_SetEventHook \
+ (*(PyDataMem_EventHookFunc * (*)(PyDataMem_EventHookFunc *, void *, void **)) \
+ PyArray_API[291])
+#define NPY_DEFAULT_ASSIGN_CASTING (*(NPY_CASTING *)PyArray_API[292])
+#define PyArray_MapIterSwapAxes \
+ (*(void (*)(PyArrayMapIterObject *, PyArrayObject **, int)) \
+ PyArray_API[293])
+#define PyArray_MapIterArray \
+ PyArray_API[294])
+#define PyArray_MapIterNext \
+ (*(void (*)(PyArrayMapIterObject *)) \
+ PyArray_API[295])
+#define PyArray_Partition \
+ (*(int (*)(PyArrayObject *, PyArrayObject *, int, NPY_SELECTKIND)) \
+ PyArray_API[296])
+#define PyArray_ArgPartition \
+ (*(PyObject * (*)(PyArrayObject *, PyArrayObject *, int, NPY_SELECTKIND)) \
+ PyArray_API[297])
+#define PyArray_SelectkindConverter \
+ (*(int (*)(PyObject *, NPY_SELECTKIND *)) \
+ PyArray_API[298])
+#define PyDataMem_NEW_ZEROED \
+ (*(void * (*)(size_t, size_t)) \
+ PyArray_API[299])
+#define PyArray_CheckAnyScalarExact \
+ PyArray_API[300])
+#define PyArray_MapIterArrayCopyIfOverlap \
+ PyArray_API[301])
+#define PyArray_ResolveWritebackIfCopy \
+ PyArray_API[302])
+#define PyArray_SetWritebackIfCopyBase \
+ PyArray_API[303])
+ "ABI version 0x%x but this version of numpy is 0x%x", \
+ "API version 0x%x but this version of numpy is 0x%x", \
@@ -0,0 +1,311 @@
+#ifdef _UMATHMODULE
+extern NPY_NO_EXPORT PyTypeObject PyUFunc_Type;
+NPY_NO_EXPORT PyObject * PyUFunc_FromFuncAndData \
+ (PyUFuncGenericFunction *, void **, char *, int, int, int, int, const char *, const char *, int);
+NPY_NO_EXPORT int PyUFunc_RegisterLoopForType \
+ (PyUFuncObject *, int, PyUFuncGenericFunction, const int *, void *);
+NPY_NO_EXPORT int PyUFunc_GenericFunction \
+ (PyUFuncObject *, PyObject *, PyObject *, PyArrayObject **);
+NPY_NO_EXPORT void PyUFunc_f_f_As_d_d \
+ (char **, npy_intp const *, npy_intp const *, void *);
+NPY_NO_EXPORT void PyUFunc_d_d \
+NPY_NO_EXPORT void PyUFunc_f_f \
+NPY_NO_EXPORT void PyUFunc_g_g \
+NPY_NO_EXPORT void PyUFunc_F_F_As_D_D \
+NPY_NO_EXPORT void PyUFunc_F_F \
+NPY_NO_EXPORT void PyUFunc_D_D \
+NPY_NO_EXPORT void PyUFunc_G_G \
+NPY_NO_EXPORT void PyUFunc_O_O \
+NPY_NO_EXPORT void PyUFunc_ff_f_As_dd_d \
+NPY_NO_EXPORT void PyUFunc_ff_f \
+NPY_NO_EXPORT void PyUFunc_dd_d \
+NPY_NO_EXPORT void PyUFunc_gg_g \
+NPY_NO_EXPORT void PyUFunc_FF_F_As_DD_D \
+NPY_NO_EXPORT void PyUFunc_DD_D \
+NPY_NO_EXPORT void PyUFunc_FF_F \
+NPY_NO_EXPORT void PyUFunc_GG_G \
+NPY_NO_EXPORT void PyUFunc_OO_O \
+NPY_NO_EXPORT void PyUFunc_O_O_method \
+NPY_NO_EXPORT void PyUFunc_OO_O_method \
+NPY_NO_EXPORT void PyUFunc_On_Om \
+NPY_NO_EXPORT int PyUFunc_GetPyValues \
+ (char *, int *, int *, PyObject **);
+NPY_NO_EXPORT int PyUFunc_checkfperr \
+ (int, PyObject *, int *);
+NPY_NO_EXPORT void PyUFunc_clearfperr \
+NPY_NO_EXPORT int PyUFunc_getfperr \
+NPY_NO_EXPORT int PyUFunc_handlefperr \
+ (int, PyObject *, int, int *);
+NPY_NO_EXPORT int PyUFunc_ReplaceLoopBySignature \
+ (PyUFuncObject *, PyUFuncGenericFunction, const int *, PyUFuncGenericFunction *);
+NPY_NO_EXPORT PyObject * PyUFunc_FromFuncAndDataAndSignature \
+ (PyUFuncGenericFunction *, void **, char *, int, int, int, int, const char *, const char *, int, const char *);
+NPY_NO_EXPORT int PyUFunc_SetUsesArraysAsData \
+ (void **, size_t);
+NPY_NO_EXPORT void PyUFunc_e_e \
+NPY_NO_EXPORT void PyUFunc_e_e_As_f_f \
+NPY_NO_EXPORT void PyUFunc_e_e_As_d_d \
+NPY_NO_EXPORT void PyUFunc_ee_e \
+NPY_NO_EXPORT void PyUFunc_ee_e_As_ff_f \
+NPY_NO_EXPORT void PyUFunc_ee_e_As_dd_d \
+NPY_NO_EXPORT int PyUFunc_DefaultTypeResolver \
+ (PyUFuncObject *, NPY_CASTING, PyArrayObject **, PyObject *, PyArray_Descr **);
+NPY_NO_EXPORT int PyUFunc_ValidateCasting \
+ (PyUFuncObject *, NPY_CASTING, PyArrayObject **, PyArray_Descr **);
+NPY_NO_EXPORT int PyUFunc_RegisterLoopForDescr \
+ (PyUFuncObject *, PyArray_Descr *, PyUFuncGenericFunction, PyArray_Descr **, void *);
+NPY_NO_EXPORT PyObject * PyUFunc_FromFuncAndDataAndSignatureAndIdentity \
+ (PyUFuncGenericFunction *, void **, char *, int, int, int, int, const char *, const char *, const int, const char *, PyObject *);
+#if defined(PY_UFUNC_UNIQUE_SYMBOL)
+#define PyUFunc_API PY_UFUNC_UNIQUE_SYMBOL
+#if defined(NO_IMPORT) || defined(NO_IMPORT_UFUNC)
+extern void **PyUFunc_API;
+void **PyUFunc_API;
+static void **PyUFunc_API=NULL;
+#define PyUFunc_Type (*(PyTypeObject *)PyUFunc_API[0])
+#define PyUFunc_FromFuncAndData \
+ (*(PyObject * (*)(PyUFuncGenericFunction *, void **, char *, int, int, int, int, const char *, const char *, int)) \
+ PyUFunc_API[1])
+#define PyUFunc_RegisterLoopForType \
+ (*(int (*)(PyUFuncObject *, int, PyUFuncGenericFunction, const int *, void *)) \
+ PyUFunc_API[2])
+#define PyUFunc_GenericFunction \
+ (*(int (*)(PyUFuncObject *, PyObject *, PyObject *, PyArrayObject **)) \
+ PyUFunc_API[3])
+#define PyUFunc_f_f_As_d_d \
+ (*(void (*)(char **, npy_intp const *, npy_intp const *, void *)) \
+ PyUFunc_API[4])
+#define PyUFunc_d_d \
+ PyUFunc_API[5])
+#define PyUFunc_f_f \
+ PyUFunc_API[6])
+#define PyUFunc_g_g \
+ PyUFunc_API[7])
+#define PyUFunc_F_F_As_D_D \
+ PyUFunc_API[8])
+#define PyUFunc_F_F \
+ PyUFunc_API[9])
+#define PyUFunc_D_D \
+ PyUFunc_API[10])
+#define PyUFunc_G_G \
+ PyUFunc_API[11])
+#define PyUFunc_O_O \
+ PyUFunc_API[12])
+#define PyUFunc_ff_f_As_dd_d \
+ PyUFunc_API[13])
+#define PyUFunc_ff_f \
+ PyUFunc_API[14])
+#define PyUFunc_dd_d \
+ PyUFunc_API[15])
+#define PyUFunc_gg_g \
+ PyUFunc_API[16])
+#define PyUFunc_FF_F_As_DD_D \
+ PyUFunc_API[17])
+#define PyUFunc_DD_D \
+ PyUFunc_API[18])
+#define PyUFunc_FF_F \
+ PyUFunc_API[19])
+#define PyUFunc_GG_G \
+ PyUFunc_API[20])
+#define PyUFunc_OO_O \
+ PyUFunc_API[21])
+#define PyUFunc_O_O_method \
+ PyUFunc_API[22])
+#define PyUFunc_OO_O_method \
+ PyUFunc_API[23])
+#define PyUFunc_On_Om \
+ PyUFunc_API[24])
+#define PyUFunc_GetPyValues \
+ (*(int (*)(char *, int *, int *, PyObject **)) \
+ PyUFunc_API[25])
+#define PyUFunc_checkfperr \
+ (*(int (*)(int, PyObject *, int *)) \
+ PyUFunc_API[26])
+#define PyUFunc_clearfperr \
+ (*(void (*)(void)) \
+ PyUFunc_API[27])
+#define PyUFunc_getfperr \
+ PyUFunc_API[28])
+#define PyUFunc_handlefperr \
+ (*(int (*)(int, PyObject *, int, int *)) \
+ PyUFunc_API[29])
+#define PyUFunc_ReplaceLoopBySignature \
+ (*(int (*)(PyUFuncObject *, PyUFuncGenericFunction, const int *, PyUFuncGenericFunction *)) \
+ PyUFunc_API[30])
+#define PyUFunc_FromFuncAndDataAndSignature \
+ (*(PyObject * (*)(PyUFuncGenericFunction *, void **, char *, int, int, int, int, const char *, const char *, int, const char *)) \
+ PyUFunc_API[31])
+#define PyUFunc_SetUsesArraysAsData \
+ (*(int (*)(void **, size_t)) \
+ PyUFunc_API[32])
+#define PyUFunc_e_e \
+ PyUFunc_API[33])
+#define PyUFunc_e_e_As_f_f \
+ PyUFunc_API[34])
+#define PyUFunc_e_e_As_d_d \
+ PyUFunc_API[35])
+#define PyUFunc_ee_e \
+ PyUFunc_API[36])
+#define PyUFunc_ee_e_As_ff_f \
+ PyUFunc_API[37])
+#define PyUFunc_ee_e_As_dd_d \
+ PyUFunc_API[38])
+#define PyUFunc_DefaultTypeResolver \
+ (*(int (*)(PyUFuncObject *, NPY_CASTING, PyArrayObject **, PyObject *, PyArray_Descr **)) \
+ PyUFunc_API[39])
+#define PyUFunc_ValidateCasting \
+ (*(int (*)(PyUFuncObject *, NPY_CASTING, PyArrayObject **, PyArray_Descr **)) \
+ PyUFunc_API[40])
+#define PyUFunc_RegisterLoopForDescr \
+ (*(int (*)(PyUFuncObject *, PyArray_Descr *, PyUFuncGenericFunction, PyArray_Descr **, void *)) \
+ PyUFunc_API[41])
+#define PyUFunc_FromFuncAndDataAndSignatureAndIdentity \
+ (*(PyObject * (*)(PyUFuncGenericFunction *, void **, char *, int, int, int, int, const char *, const char *, const int, const char *, PyObject *)) \
+ PyUFunc_API[42])
+static NPY_INLINE int
+_import_umath(void)
+ PyErr_SetString(PyExc_ImportError,
+ "numpy.core._multiarray_umath failed to import");
+ c_api = PyObject_GetAttrString(numpy, "_UFUNC_API");
+ PyErr_SetString(PyExc_AttributeError, "_UFUNC_API not found");
+ PyErr_SetString(PyExc_RuntimeError, "_UFUNC_API is not PyCapsule object");
+ PyUFunc_API = (void **)PyCapsule_GetPointer(c_api, NULL);
+ if (PyUFunc_API == NULL) {
+ PyErr_SetString(PyExc_RuntimeError, "_UFUNC_API is NULL pointer");
+#define import_umath() \
+ do {\
+ UFUNC_NOFPE\
+ if (_import_umath() < 0) {\
+ PyErr_Print();\
+ PyErr_SetString(PyExc_ImportError,\
+ "numpy.core.umath failed to import");\
+ return NULL;\
+ }\
+ } while(0)
+#define import_umath1(ret) \
+ return ret;\
+#define import_umath2(ret, msg) \
+ PyErr_SetString(PyExc_ImportError, msg);\
+#define import_ufunc() \
@@ -0,0 +1,90 @@
+#ifndef _NPY_INCLUDE_NEIGHBORHOOD_IMP
+#error You should not include this header directly
+/*
+ * Private API (here for inline)
+_PyArrayNeighborhoodIter_IncrCoord(PyArrayNeighborhoodIterObject* iter);
+ * Update to next item of the iterator
+ *
+ * Note: this simply increment the coordinates vector, last dimension
+ * incremented first , i.e, for dimension 3
+ * ...
+ * -1, -1, -1
+ * -1, -1, 0
+ * -1, -1, 1
+ * ....
+ * -1, 0, -1
+ * -1, 0, 0
+ * 0, -1, -1
+ * 0, -1, 0
+#define _UPDATE_COORD_ITER(c) \
+ wb = iter->coordinates[c] < iter->bounds[c][1]; \
+ if (wb) { \
+ iter->coordinates[c] += 1; \
+ return 0; \
+ } \
+ else { \
+ iter->coordinates[c] = iter->bounds[c][0]; \
+_PyArrayNeighborhoodIter_IncrCoord(PyArrayNeighborhoodIterObject* iter)
+ npy_intp i, wb;
+ for (i = iter->nd - 1; i >= 0; --i) {
+ _UPDATE_COORD_ITER(i)
+ * Version optimized for 2d arrays, manual loop unrolling
+_PyArrayNeighborhoodIter_IncrCoord2D(PyArrayNeighborhoodIterObject* iter)
+ npy_intp wb;
+ _UPDATE_COORD_ITER(1)
+ _UPDATE_COORD_ITER(0)
+#undef _UPDATE_COORD_ITER
+ * Advance to the next neighbour
+PyArrayNeighborhoodIter_Next(PyArrayNeighborhoodIterObject* iter)
+ _PyArrayNeighborhoodIter_IncrCoord (iter);
+ iter->dataptr = iter->translate((PyArrayIterObject*)iter, iter->coordinates);
+ * Reset functions
+PyArrayNeighborhoodIter_Reset(PyArrayNeighborhoodIterObject* iter)
+ npy_intp i;
+ for (i = 0; i < iter->nd; ++i) {
+ iter->coordinates[i] = iter->bounds[i][0];
@@ -0,0 +1,29 @@
+#define NPY_SIZEOF_SHORT SIZEOF_SHORT
+#define NPY_SIZEOF_INT SIZEOF_INT
+#define NPY_SIZEOF_LONG SIZEOF_LONG
+#define NPY_SIZEOF_FLOAT 4
+#define NPY_SIZEOF_COMPLEX_FLOAT 8
+#define NPY_SIZEOF_DOUBLE 8
+#define NPY_SIZEOF_COMPLEX_DOUBLE 16
+#define NPY_SIZEOF_LONGDOUBLE 8
+#define NPY_SIZEOF_COMPLEX_LONGDOUBLE 16
+#define NPY_SIZEOF_PY_INTPTR_T 8
+#define NPY_SIZEOF_OFF_T 4
+#define NPY_SIZEOF_PY_LONG_LONG 8
+#define NPY_SIZEOF_LONGLONG 8
+#define NPY_NO_SIGNAL 1
+#define NPY_NO_SMP 0
+#define NPY_HAVE_DECL_ISNAN
+#define NPY_HAVE_DECL_ISINF
+#define NPY_HAVE_DECL_SIGNBIT
+#define NPY_HAVE_DECL_ISFINITE
+#define NPY_USE_C99_COMPLEX 1
+#define NPY_RELAXED_STRIDES_CHECKING 1
+#define NPY_USE_C99_FORMATS 1
+#define NPY_VISIBILITY_HIDDEN
+#define NPY_ABI_VERSION 0x01000009
+#define NPY_API_VERSION 0x0000000E
+#ifndef __STDC_FORMAT_MACROS
+#define __STDC_FORMAT_MACROS 1
@@ -0,0 +1,11 @@
+#ifndef Py_ARRAYOBJECT_H
+#define Py_ARRAYOBJECT_H
+#include "ndarrayobject.h"
+#include "npy_interrupt.h"
+#ifdef NPY_NO_PREFIX
+#include "noprefix.h"
@@ -0,0 +1,182 @@
+#ifndef _NPY_ARRAYSCALARS_H_
+#define _NPY_ARRAYSCALARS_H_
+#ifndef _MULTIARRAYMODULE
+ signed char obval;
+} PyByteScalarObject;
+ short obval;
+} PyShortScalarObject;
+ int obval;
+} PyIntScalarObject;
+ long obval;
+} PyLongScalarObject;
+ npy_longlong obval;
+} PyLongLongScalarObject;
+ unsigned char obval;
+} PyUByteScalarObject;
+ unsigned short obval;
+} PyUShortScalarObject;
+ unsigned int obval;
+} PyUIntScalarObject;
+ unsigned long obval;
+} PyULongScalarObject;
+ npy_ulonglong obval;
+} PyULongLongScalarObject;
+ npy_half obval;
+} PyHalfScalarObject;
+ float obval;
+} PyFloatScalarObject;
+ double obval;
+} PyDoubleScalarObject;
+ npy_longdouble obval;
+} PyLongDoubleScalarObject;
+ npy_cfloat obval;
+} PyCFloatScalarObject;
+ npy_cdouble obval;
+} PyCDoubleScalarObject;
+ npy_clongdouble obval;
+} PyCLongDoubleScalarObject;
+ PyObject * obval;
+} PyObjectScalarObject;
+ npy_datetime obval;
+ PyArray_DatetimeMetaData obmeta;
+} PyDatetimeScalarObject;
+ npy_timedelta obval;
+} PyTimedeltaScalarObject;
+ char obval;
+} PyScalarObject;
+#define PyStringScalarObject PyBytesObject
+ /* note that the PyObject_HEAD macro lives right here */
+ PyUnicodeObject base;
+ Py_UCS4 *obval;
+ char *buffer_fmt;
+} PyUnicodeScalarObject;
+ PyObject_VAR_HEAD
+ char *obval;
+ PyArray_Descr *descr;
+ int flags;
+ PyObject *base;
+ void *_buffer_info; /* private buffer info, tagged to allow warning */
+} PyVoidScalarObject;
+/* Macros
+ Py<Cls><bitsize>ScalarObject
+ Py<Cls><bitsize>ArrType_Type
+ are defined in ndarrayobject.h
+#define PyArrayScalar_False ((PyObject *)(&(_PyArrayScalar_BoolValues[0])))
+#define PyArrayScalar_True ((PyObject *)(&(_PyArrayScalar_BoolValues[1])))
+#define PyArrayScalar_FromLong(i) \
+ ((PyObject *)(&(_PyArrayScalar_BoolValues[((i)!=0)])))
+#define PyArrayScalar_RETURN_BOOL_FROM_LONG(i) \
+ return Py_INCREF(PyArrayScalar_FromLong(i)), \
+ PyArrayScalar_FromLong(i)
+#define PyArrayScalar_RETURN_FALSE \
+ return Py_INCREF(PyArrayScalar_False), \
+ PyArrayScalar_False
+#define PyArrayScalar_RETURN_TRUE \
+ return Py_INCREF(PyArrayScalar_True), \
+ PyArrayScalar_True
+#define PyArrayScalar_New(cls) \
+ Py##cls##ArrType_Type.tp_alloc(&Py##cls##ArrType_Type, 0)
+#define PyArrayScalar_VAL(obj, cls) \
+ ((Py##cls##ScalarObject *)obj)->obval
+#define PyArrayScalar_ASSIGN(obj, cls, val) \
+ PyArrayScalar_VAL(obj, cls) = val
@@ -0,0 +1,70 @@
+#ifndef __NPY_HALFFLOAT_H__
+#define __NPY_HALFFLOAT_H__
+#include <Python.h>
+#include <numpy/npy_math.h>
+#ifdef __cplusplus
+extern "C" {
+ * Half-precision routines
+/* Conversions */
+float npy_half_to_float(npy_half h);
+double npy_half_to_double(npy_half h);
+npy_half npy_float_to_half(float f);
+npy_half npy_double_to_half(double d);
+/* Comparisons */
+int npy_half_eq(npy_half h1, npy_half h2);
+int npy_half_ne(npy_half h1, npy_half h2);
+int npy_half_le(npy_half h1, npy_half h2);
+int npy_half_lt(npy_half h1, npy_half h2);
+int npy_half_ge(npy_half h1, npy_half h2);
+int npy_half_gt(npy_half h1, npy_half h2);
+/* faster *_nonan variants for when you know h1 and h2 are not NaN */
+int npy_half_eq_nonan(npy_half h1, npy_half h2);
+int npy_half_lt_nonan(npy_half h1, npy_half h2);
+int npy_half_le_nonan(npy_half h1, npy_half h2);
+/* Miscellaneous functions */
+int npy_half_iszero(npy_half h);
+int npy_half_isnan(npy_half h);
+int npy_half_isinf(npy_half h);
+int npy_half_isfinite(npy_half h);
+int npy_half_signbit(npy_half h);
+npy_half npy_half_copysign(npy_half x, npy_half y);
+npy_half npy_half_spacing(npy_half h);
+npy_half npy_half_nextafter(npy_half x, npy_half y);
+npy_half npy_half_divmod(npy_half x, npy_half y, npy_half *modulus);
+ * Half-precision constants
+#define NPY_HALF_ZERO (0x0000u)
+#define NPY_HALF_PZERO (0x0000u)
+#define NPY_HALF_NZERO (0x8000u)
+#define NPY_HALF_ONE (0x3c00u)
+#define NPY_HALF_NEGONE (0xbc00u)
+#define NPY_HALF_PINF (0x7c00u)
+#define NPY_HALF_NINF (0xfc00u)
+#define NPY_HALF_NAN (0x7e00u)
+#define NPY_MAX_HALF (0x7bffu)
+ * Bit-level conversions
+npy_uint16 npy_floatbits_to_halfbits(npy_uint32 f);
+npy_uint16 npy_doublebits_to_halfbits(npy_uint64 d);
+npy_uint32 npy_halfbits_to_floatbits(npy_uint16 h);
+npy_uint64 npy_halfbits_to_doublebits(npy_uint16 h);
@@ -0,0 +1,2474 @@
+::
+ unsigned int
+ PyArray_GetNDArrayCVersion(void )
+Included at the very first so not auto-grabbed and thus not labeled.
+ int
+ PyArray_SetNumericOps(PyObject *dict)
+Set internal structure with number functions that all arrays will use
+ PyObject *
+ PyArray_GetNumericOps(void )
+Get dictionary showing number functions that all arrays will use
+ PyArray_INCREF(PyArrayObject *mp)
+For object arrays, increment all internal references.
+ PyArray_XDECREF(PyArrayObject *mp)
+Decrement all internal references for object arrays.
+(or arrays with object fields)
+ void
+ PyArray_SetStringFunction(PyObject *op, int repr)
+Set the array print function to be a Python function.
+ PyArray_Descr *
+ PyArray_DescrFromType(int type)
+Get the PyArray_Descr structure for a type.
+ PyArray_TypeObjectFromType(int type)
+Get a typeobject from a type-number -- can return NULL.
+New reference
+ char *
+ PyArray_Zero(PyArrayObject *arr)
+Get pointer to zero of correct type for array.
+ PyArray_One(PyArrayObject *arr)
+Get pointer to one of correct type for array
+ PyArray_CastToType(PyArrayObject *arr, PyArray_Descr *dtype, int
+ is_f_order)
+For backward compatibility
+Cast an array using typecode structure.
+steals reference to dtype --- cannot be NULL
+This function always makes a copy of arr, even if the dtype
+doesn't change.
+ PyArray_CastTo(PyArrayObject *out, PyArrayObject *mp)
+Cast to an already created array.
+ PyArray_CastAnyTo(PyArrayObject *out, PyArrayObject *mp)
+Cast to an already created array. Arrays don't have to be "broadcastable"
+Only requirement is they have the same number of elements.
+ PyArray_CanCastSafely(int fromtype, int totype)
+Check the type coercion rules.
+ npy_bool
+ PyArray_CanCastTo(PyArray_Descr *from, PyArray_Descr *to)
+leaves reference count alone --- cannot be NULL
+PyArray_CanCastTypeTo is equivalent to this, but adds a 'casting'
+parameter.
+ PyArray_ObjectType(PyObject *op, int minimum_type)
+Return the typecode of the array a Python object would be converted to
+Returns the type number the result should have, or NPY_NOTYPE on error.
+ PyArray_DescrFromObject(PyObject *op, PyArray_Descr *mintype)
+new reference -- accepts NULL for mintype
+ PyArrayObject **
+ PyArray_ConvertToCommonType(PyObject *op, int *retn)
+This function is only used in one place within NumPy and should
+generally be avoided. It is provided mainly for backward compatibility.
+The user of the function has to free the returned array.
+ PyArray_DescrFromScalar(PyObject *sc)
+Return descr object from array scalar.
+ PyArray_DescrFromTypeObject(PyObject *type)
+ npy_intp
+ PyArray_Size(PyObject *op)
+Compute the size of an array (in number of items)
+ PyArray_Scalar(void *data, PyArray_Descr *descr, PyObject *base)
+Get scalar-equivalent to a region of memory described by a descriptor.
+ PyArray_FromScalar(PyObject *scalar, PyArray_Descr *outcode)
+Get 0-dim array from scalar
+0-dim array from array-scalar object
+always contains a copy of the data
+unless outcode is NULL, it is of void type and the referrer does
+not own it either.
+steals reference to outcode
+ PyArray_ScalarAsCtype(PyObject *scalar, void *ctypeptr)
+Convert to c-type
+no error checking is performed -- ctypeptr must be same type as scalar
+in case of flexible type, the data is not copied
+into ctypeptr which is expected to be a pointer to pointer
+ PyArray_CastScalarToCtype(PyObject *scalar, void
+ *ctypeptr, PyArray_Descr *outcode)
+Cast Scalar to c-type
+The output buffer must be large-enough to receive the value
+Even for flexible types which is different from ScalarAsCtype
+where only a reference for flexible types is returned
+This may not work right on narrow builds for NumPy unicode scalars.
+ PyArray_CastScalarDirect(PyObject *scalar, PyArray_Descr
+ *indescr, void *ctypeptr, int outtype)
+ PyArray_ScalarFromObject(PyObject *object)
+Get an Array Scalar From a Python Object
+Returns NULL if unsuccessful but error is only set if another error occurred.
+Currently only Numeric-like object supported.
+ PyArray_VectorUnaryFunc *
+ PyArray_GetCastFunc(PyArray_Descr *descr, int type_num)
+Get a cast function to cast from the input descriptor to the
+output type_number (must be a registered data-type).
+Returns NULL if un-successful.
+ PyArray_FromDims(int NPY_UNUSED(nd) , int *NPY_UNUSED(d) , int
+ NPY_UNUSED(type) )
+Deprecated, use PyArray_SimpleNew instead.
+ PyArray_FromDimsAndDataAndDescr(int NPY_UNUSED(nd) , int
+ *NPY_UNUSED(d) , PyArray_Descr
+ *descr, char *NPY_UNUSED(data) )
+Deprecated, use PyArray_NewFromDescr instead.
+ PyArray_FromAny(PyObject *op, PyArray_Descr *newtype, int
+ min_depth, int max_depth, int flags, PyObject
+ *context)
+Does not check for NPY_ARRAY_ENSURECOPY and NPY_ARRAY_NOTSWAPPED in flags
+Steals a reference to newtype --- which can be NULL
+ PyArray_EnsureArray(PyObject *op)
+This is a quick wrapper around
+PyArray_FromAny(op, NULL, 0, 0, NPY_ARRAY_ENSUREARRAY, NULL)
+that special cases Arrays and PyArray_Scalars up front
+It *steals a reference* to the object
+It also guarantees that the result is PyArray_Type
+Because it decrefs op if any conversion needs to take place
+so it can be used like PyArray_EnsureArray(some_function(...))
+ PyArray_EnsureAnyArray(PyObject *op)
+ PyArray_FromFile(FILE *fp, PyArray_Descr *dtype, npy_intp num, char
+ *sep)
+Given a ``FILE *`` pointer ``fp``, and a ``PyArray_Descr``, return an
+array corresponding to the data encoded in that file.
+The reference to `dtype` is stolen (it is possible that the passed in
+dtype is not held on to).
+The number of elements to read is given as ``num``; if it is < 0, then
+then as many as possible are read.
+If ``sep`` is NULL or empty, then binary data is assumed, else
+text data, with ``sep`` as the separator between elements. Whitespace in
+the separator matches any length of whitespace in the text, and a match
+for whitespace around the separator is added.
+For memory-mapped files, use the buffer interface. No more data than
+necessary is read by this routine.
+ PyArray_FromString(char *data, npy_intp slen, PyArray_Descr
+ *dtype, npy_intp num, char *sep)
+Given a pointer to a string ``data``, a string length ``slen``, and
+a ``PyArray_Descr``, return an array corresponding to the data
+encoded in that string.
+If the dtype is NULL, the default array type is used (double).
+If non-null, the reference is stolen.
+If ``slen`` is < 0, then the end of string is used for text data.
+It is an error for ``slen`` to be < 0 for binary data (since embedded NULLs
+would be the norm).
+ PyArray_FromBuffer(PyObject *buf, PyArray_Descr *type, npy_intp
+ count, npy_intp offset)
+ PyArray_FromIter(PyObject *obj, PyArray_Descr *dtype, npy_intp count)
+steals a reference to dtype (which cannot be NULL)
+ PyArray_Return(PyArrayObject *mp)
+Return either an array or the appropriate Python object if the array
+is 0d and matches a Python type.
+steals reference to mp
+ PyArray_GetField(PyArrayObject *self, PyArray_Descr *typed, int
+ offset)
+Get a subset of bytes from each element of the array
+steals reference to typed, must not be NULL
+ PyArray_SetField(PyArrayObject *self, PyArray_Descr *dtype, int
+ offset, PyObject *val)
+Set a subset of bytes from each element of the array
+steals reference to dtype, must not be NULL
+ PyArray_Byteswap(PyArrayObject *self, npy_bool inplace)
+ PyArray_Resize(PyArrayObject *self, PyArray_Dims *newshape, int
+ refcheck, NPY_ORDER NPY_UNUSED(order) )
+Resize (reallocate data). Only works if nothing else is referencing this
+array and it is contiguous. If refcheck is 0, then the reference count is
+not checked and assumed to be 1. You still must own this data and have no
+weak-references and no base object.
+ PyArray_MoveInto(PyArrayObject *dst, PyArrayObject *src)
+Move the memory of one array into another, allowing for overlapping data.
+Returns 0 on success, negative on failure.
+ PyArray_CopyInto(PyArrayObject *dst, PyArrayObject *src)
+Copy an Array into another array.
+Broadcast to the destination shape if necessary.
+Returns 0 on success, -1 on failure.
+ PyArray_CopyAnyInto(PyArrayObject *dst, PyArrayObject *src)
+Copy an Array into another array -- memory must not overlap
+Does not require src and dest to have "broadcastable" shapes
+(only the same number of elements).
+TODO: For NumPy 2.0, this could accept an order parameter which
+only allows NPY_CORDER and NPY_FORDER. Could also rename
+this to CopyAsFlat to make the name more intuitive.
+Returns 0 on success, -1 on error.
+ PyArray_CopyObject(PyArrayObject *dest, PyObject *src_object)
+ PyArray_NewCopy(PyArrayObject *obj, NPY_ORDER order)
+Copy an array.
+ PyArray_ToList(PyArrayObject *self)
+To List
+ PyArray_ToString(PyArrayObject *self, NPY_ORDER order)
+ PyArray_ToFile(PyArrayObject *self, FILE *fp, char *sep, char *format)
+To File
+ PyArray_Dump(PyObject *self, PyObject *file, int protocol)
+ PyArray_Dumps(PyObject *self, int protocol)
+ PyArray_ValidType(int type)
+Is the typenum valid?
+ PyArray_UpdateFlags(PyArrayObject *ret, int flagmask)
+Update Several Flags at once.
+ PyArray_New(PyTypeObject *subtype, int nd, npy_intp const *dims, int
+ type_num, npy_intp const *strides, void *data, int
+ itemsize, int flags, PyObject *obj)
+Generic new array creation routine.
+ PyArray_NewFromDescr(PyTypeObject *subtype, PyArray_Descr *descr, int
+ nd, npy_intp const *dims, npy_intp const
+ *strides, void *data, int flags, PyObject *obj)
+steals a reference to descr. On failure or when dtype->subarray is
+true, dtype will be decrefed.
+ PyArray_DescrNew(PyArray_Descr *base)
+base cannot be NULL
+ PyArray_DescrNewFromType(int type_num)
+ double
+ PyArray_GetPriority(PyObject *obj, double default_)
+Get Priority from object
+ PyArray_IterNew(PyObject *obj)
+Get Iterator.
+ PyObject*
+ PyArray_MultiIterNew(int n, ... )
+Get MultiIterator,
+ PyArray_PyIntAsInt(PyObject *o)
+ PyArray_PyIntAsIntp(PyObject *o)
+ PyArray_Broadcast(PyArrayMultiIterObject *mit)
+ PyArray_FillObjectArray(PyArrayObject *arr, PyObject *obj)
+Assumes contiguous
+ PyArray_FillWithScalar(PyArrayObject *arr, PyObject *obj)
+ PyArray_CheckStrides(int elsize, int nd, npy_intp numbytes, npy_intp
+ offset, npy_intp const *dims, npy_intp const
+ *newstrides)
+ PyArray_DescrNewByteorder(PyArray_Descr *self, char newendian)
+returns a copy of the PyArray_Descr structure with the byteorder
+altered:
+no arguments: The byteorder is swapped (in all subfields as well)
+single argument: The byteorder is forced to the given state
+(in all subfields as well)
+Valid states: ('big', '>') or ('little' or '<')
+('native', or '=')
+If a descr structure with | is encountered it's own
+byte-order is not changed but any fields are:
+Deep bytorder change of a data-type descriptor
+Leaves reference count of self unchanged --- does not DECREF self ***
+ PyArray_IterAllButAxis(PyObject *obj, int *inaxis)
+Get Iterator that iterates over all but one axis (don't use this with
+PyArray_ITER_GOTO1D). The axis will be over-written if negative
+with the axis having the smallest stride.
+ PyArray_CheckFromAny(PyObject *op, PyArray_Descr *descr, int
+ min_depth, int max_depth, int requires, PyObject
+steals a reference to descr -- accepts NULL
+ PyArray_FromArray(PyArrayObject *arr, PyArray_Descr *newtype, int
+ flags)
+steals reference to newtype --- acc. NULL
+ PyArray_FromInterface(PyObject *origin)
+ PyArray_FromStructInterface(PyObject *input)
+ PyArray_FromArrayAttr(PyObject *op, PyArray_Descr *typecode, PyObject
+ NPY_SCALARKIND
+ PyArray_ScalarKind(int typenum, PyArrayObject **arr)
+ScalarKind
+Returns the scalar kind of a type number, with an
+optional tweak based on the scalar value itself.
+If no scalar is provided, it returns INTPOS_SCALAR
+for both signed and unsigned integers, otherwise
+it checks the sign of any signed integer to choose
+INTNEG_SCALAR when appropriate.
+ PyArray_CanCoerceScalar(int thistype, int neededtype, NPY_SCALARKIND
+ scalar)
+Determines whether the data type 'thistype', with
+scalar kind 'scalar', can be coerced into 'neededtype'.
+ PyArray_NewFlagsObject(PyObject *obj)
+Get New ArrayFlagsObject
+ PyArray_CanCastScalar(PyTypeObject *from, PyTypeObject *to)
+See if array scalars can be cast.
+TODO: For NumPy 2.0, add a NPY_CASTING parameter.
+ PyArray_CompareUCS4(npy_ucs4 const *s1, npy_ucs4 const *s2, size_t
+ len)
+ PyArray_RemoveSmallest(PyArrayMultiIterObject *multi)
+Adjusts previously broadcasted iterators so that the axis with
+the smallest sum of iterator strides is not iterated over.
+Returns dimension which is smallest in the range [0,multi->nd).
+A -1 is returned if multi->nd == 0.
+don't use with PyArray_ITER_GOTO1D because factors are not adjusted
+ PyArray_ElementStrides(PyObject *obj)
+ PyArray_Item_INCREF(char *data, PyArray_Descr *descr)
+XINCREF all objects in a single array item. This is complicated for
+structured datatypes where the position of objects needs to be extracted.
+The function is execute recursively for each nested field or subarrays dtype
+such as as `np.dtype([("field1", "O"), ("field2", "f,O", (3,2))])`
+ PyArray_Item_XDECREF(char *data, PyArray_Descr *descr)
+XDECREF all objects in a single array item. This is complicated for
+ PyArray_FieldNames(PyObject *fields)
+Return the tuple of ordered field names from a dictionary.
+ PyArray_Transpose(PyArrayObject *ap, PyArray_Dims *permute)
+Return Transpose.
+ PyArray_TakeFrom(PyArrayObject *self0, PyObject *indices0, int
+ axis, PyArrayObject *out, NPY_CLIPMODE clipmode)
+Take
+ PyArray_PutTo(PyArrayObject *self, PyObject*values0, PyObject
+ *indices0, NPY_CLIPMODE clipmode)
+Put values into an array
+ PyArray_PutMask(PyArrayObject *self, PyObject*values0, PyObject*mask0)
+Put values into an array according to a mask.
+ PyArray_Repeat(PyArrayObject *aop, PyObject *op, int axis)
+Repeat the array.
+ PyArray_Choose(PyArrayObject *ip, PyObject *op, PyArrayObject
+ *out, NPY_CLIPMODE clipmode)
+ PyArray_Sort(PyArrayObject *op, int axis, NPY_SORTKIND which)
+Sort an array in-place
+ PyArray_ArgSort(PyArrayObject *op, int axis, NPY_SORTKIND which)
+ArgSort an array
+ PyArray_SearchSorted(PyArrayObject *op1, PyObject *op2, NPY_SEARCHSIDE
+ side, PyObject *perm)
+Search the sorted array op1 for the location of the items in op2. The
+result is an array of indexes, one for each element in op2, such that if
+the item were to be inserted in op1 just before that index the array
+would still be in sorted order.
+Parameters
+----------
+op1 : PyArrayObject *
+Array to be searched, must be 1-D.
+op2 : PyObject *
+Array of items whose insertion indexes in op1 are wanted
+side : {NPY_SEARCHLEFT, NPY_SEARCHRIGHT}
+If NPY_SEARCHLEFT, return first valid insertion indexes
+If NPY_SEARCHRIGHT, return last valid insertion indexes
+perm : PyObject *
+Permutation array that sorts op1 (optional)
+Returns
+-------
+ret : PyObject *
+New reference to npy_intp array containing indexes where items in op2
+could be validly inserted into op1. NULL on error.
+Notes
+-----
+Binary search is used to find the indexes.
+ PyArray_ArgMax(PyArrayObject *op, int axis, PyArrayObject *out)
+ArgMax
+ PyArray_ArgMin(PyArrayObject *op, int axis, PyArrayObject *out)
+ArgMin
+ PyArray_Reshape(PyArrayObject *self, PyObject *shape)
+Reshape
+ PyArray_Newshape(PyArrayObject *self, PyArray_Dims *newdims, NPY_ORDER
+ order)
+New shape for an array
+ PyArray_Squeeze(PyArrayObject *self)
+return a new view of the array object with all of its unit-length
+dimensions squeezed out if needed, otherwise
+return the same array.
+ PyArray_View(PyArrayObject *self, PyArray_Descr *type, PyTypeObject
+ *pytype)
+View
+steals a reference to type -- accepts NULL
+ PyArray_SwapAxes(PyArrayObject *ap, int a1, int a2)
+SwapAxes
+ PyArray_Max(PyArrayObject *ap, int axis, PyArrayObject *out)
+Max
+ PyArray_Min(PyArrayObject *ap, int axis, PyArrayObject *out)
+Min
+ PyArray_Ptp(PyArrayObject *ap, int axis, PyArrayObject *out)
+Ptp
+ PyArray_Mean(PyArrayObject *self, int axis, int rtype, PyArrayObject
+ *out)
+Mean
+ PyArray_Trace(PyArrayObject *self, int offset, int axis1, int
+ axis2, int rtype, PyArrayObject *out)
+Trace
+ PyArray_Diagonal(PyArrayObject *self, int offset, int axis1, int
+ axis2)
+Diagonal
+In NumPy versions prior to 1.7, this function always returned a copy of
+the diagonal array. In 1.7, the code has been updated to compute a view
+onto 'self', but it still copies this array before returning, as well as
+setting the internal WARN_ON_WRITE flag. In a future version, it will
+simply return a view onto self.
+ PyArray_Clip(PyArrayObject *self, PyObject *min, PyObject
+ *max, PyArrayObject *out)
+Clip
+ PyArray_Conjugate(PyArrayObject *self, PyArrayObject *out)
+Conjugate
+ PyArray_Nonzero(PyArrayObject *self)
+Nonzero
+TODO: In NumPy 2.0, should make the iteration order a parameter.
+ PyArray_Std(PyArrayObject *self, int axis, int rtype, PyArrayObject
+ *out, int variance)
+Set variance to 1 to by-pass square-root calculation and return variance
+Std
+ PyArray_Sum(PyArrayObject *self, int axis, int rtype, PyArrayObject
+Sum
+ PyArray_CumSum(PyArrayObject *self, int axis, int rtype, PyArrayObject
+CumSum
+ PyArray_Prod(PyArrayObject *self, int axis, int rtype, PyArrayObject
+Prod
+ PyArray_CumProd(PyArrayObject *self, int axis, int
+ rtype, PyArrayObject *out)
+CumProd
+ PyArray_All(PyArrayObject *self, int axis, PyArrayObject *out)
+All
+ PyArray_Any(PyArrayObject *self, int axis, PyArrayObject *out)
+Any
+ PyArray_Compress(PyArrayObject *self, PyObject *condition, int
+ axis, PyArrayObject *out)
+Compress
+ PyArray_Flatten(PyArrayObject *a, NPY_ORDER order)
+Flatten
+ PyArray_Ravel(PyArrayObject *arr, NPY_ORDER order)
+Ravel
+Returns a contiguous array
+ PyArray_MultiplyList(npy_intp const *l1, int n)
+Multiply a List
+ PyArray_MultiplyIntList(int const *l1, int n)
+Multiply a List of ints
+ void *
+ PyArray_GetPtr(PyArrayObject *obj, npy_intp const*ind)
+Produce a pointer into array
+ PyArray_CompareLists(npy_intp const *l1, npy_intp const *l2, int n)
+Compare Lists
+ PyArray_AsCArray(PyObject **op, void *ptr, npy_intp *dims, int
+ nd, PyArray_Descr*typedescr)
+Simulate a C-array
+steals a reference to typedescr -- can be NULL
+ PyArray_As1D(PyObject **NPY_UNUSED(op) , char **NPY_UNUSED(ptr) , int
+ *NPY_UNUSED(d1) , int NPY_UNUSED(typecode) )
+Convert to a 1D C-array
+ PyArray_As2D(PyObject **NPY_UNUSED(op) , char ***NPY_UNUSED(ptr) , int
+ *NPY_UNUSED(d1) , int *NPY_UNUSED(d2) , int
+ NPY_UNUSED(typecode) )
+Convert to a 2D C-array
+ PyArray_Free(PyObject *op, void *ptr)
+Free pointers created if As2D is called
+ PyArray_Converter(PyObject *object, PyObject **address)
+Useful to pass as converter function for O& processing in PyArgs_ParseTuple.
+This conversion function can be used with the "O&" argument for
+PyArg_ParseTuple. It will immediately return an object of array type
+or will convert to a NPY_ARRAY_CARRAY any other object.
+If you use PyArray_Converter, you must DECREF the array when finished
+as you get a new reference to it.
+ PyArray_IntpFromSequence(PyObject *seq, npy_intp *vals, int maxvals)
+PyArray_IntpFromSequence
+Returns the number of integers converted or -1 if an error occurred.
+vals must be large enough to hold maxvals
+ PyArray_Concatenate(PyObject *op, int axis)
+Concatenate
+Concatenate an arbitrary Python sequence into an array.
+op is a python object supporting the sequence interface.
+Its elements will be concatenated together to form a single
+multidimensional array. If axis is NPY_MAXDIMS or bigger, then
+each sequence object will be flattened before concatenation
+ PyArray_InnerProduct(PyObject *op1, PyObject *op2)
+Numeric.innerproduct(a,v)
+ PyArray_MatrixProduct(PyObject *op1, PyObject *op2)
+Numeric.matrixproduct(a,v)
+just like inner product but does the swapaxes stuff on the fly
+ PyArray_CopyAndTranspose(PyObject *op)
+Copy and Transpose
+Could deprecate this function, as there isn't a speed benefit over
+calling Transpose and then Copy.
+ PyArray_Correlate(PyObject *op1, PyObject *op2, int mode)
+Numeric.correlate(a1,a2,mode)
+ PyArray_TypestrConvert(int itemsize, int gentype)
+Typestr converter
+ PyArray_DescrConverter(PyObject *obj, PyArray_Descr **at)
+Get typenum from an object -- None goes to NPY_DEFAULT_TYPE
+This function takes a Python object representing a type and converts it
+to a the correct PyArray_Descr * structure to describe the type.
+Many objects can be used to represent a data-type which in NumPy is
+quite a flexible concept.
+This is the central code that converts Python objects to
+Type-descriptor objects that are used throughout numpy.
+Returns a new reference in *at, but the returned should not be
+modified as it may be one of the canonical immutable objects or
+a reference to the input obj.
+ PyArray_DescrConverter2(PyObject *obj, PyArray_Descr **at)
+Get typenum from an object -- None goes to NULL
+ PyArray_IntpConverter(PyObject *obj, PyArray_Dims *seq)
+Get intp chunk from sequence
+This function takes a Python sequence object and allocates and
+fills in an intp array with the converted values.
+Remember to free the pointer seq.ptr when done using
+PyDimMem_FREE(seq.ptr)**
+ PyArray_BufferConverter(PyObject *obj, PyArray_Chunk *buf)
+Get buffer chunk from object
+this function takes a Python object which exposes the (single-segment)
+buffer interface and returns a pointer to the data segment
+You should increment the reference count by one of buf->base
+if you will hang on to a reference
+You only get a borrowed reference to the object. Do not free the
+memory...
+ PyArray_AxisConverter(PyObject *obj, int *axis)
+Get axis from an object (possibly None) -- a converter function,
+See also PyArray_ConvertMultiAxis, which also handles a tuple of axes.
+ PyArray_BoolConverter(PyObject *object, npy_bool *val)
+Convert an object to true / false
+ PyArray_ByteorderConverter(PyObject *obj, char *endian)
+Convert object to endian
+ PyArray_OrderConverter(PyObject *object, NPY_ORDER *val)
+Convert an object to FORTRAN / C / ANY / KEEP
+ unsigned char
+ PyArray_EquivTypes(PyArray_Descr *type1, PyArray_Descr *type2)
+This function returns true if the two typecodes are
+equivalent (same basic kind and same itemsize).
+ PyArray_Zeros(int nd, npy_intp const *dims, PyArray_Descr *type, int
+Zeros
+steals a reference to type. On failure or when dtype->subarray is
+accepts NULL type
+ PyArray_Empty(int nd, npy_intp const *dims, PyArray_Descr *type, int
+Empty
+steals a reference to type
+ PyArray_Where(PyObject *condition, PyObject *x, PyObject *y)
+Where
+ PyArray_Arange(double start, double stop, double step, int type_num)
+Arange,
+ PyArray_ArangeObj(PyObject *start, PyObject *stop, PyObject
+ *step, PyArray_Descr *dtype)
+ArangeObj,
+this doesn't change the references
+ PyArray_SortkindConverter(PyObject *obj, NPY_SORTKIND *sortkind)
+Convert object to sort kind
+ PyArray_LexSort(PyObject *sort_keys, int axis)
+LexSort an array providing indices that will sort a collection of arrays
+lexicographically. The first key is sorted on first, followed by the second key
+-- requires that arg"merge"sort is available for each sort_key
+Returns an index array that shows the indexes for the lexicographic sort along
+the given axis.
+ PyArray_Round(PyArrayObject *a, int decimals, PyArrayObject *out)
+Round
+ PyArray_EquivTypenums(int typenum1, int typenum2)
+ PyArray_RegisterDataType(PyArray_Descr *descr)
+Register Data type
+Does not change the reference count of descr
+ PyArray_RegisterCastFunc(PyArray_Descr *descr, int
+ totype, PyArray_VectorUnaryFunc *castfunc)
+Register Casting Function
+Replaces any function currently stored.
+ PyArray_RegisterCanCast(PyArray_Descr *descr, int
+ totype, NPY_SCALARKIND scalar)
+Register a type number indicating that a descriptor can be cast
+to it safely
+ PyArray_InitArrFuncs(PyArray_ArrFuncs *f)
+Initialize arrfuncs to NULL
+ PyArray_IntTupleFromIntp(int len, npy_intp const *vals)
+PyArray_IntTupleFromIntp
+ PyArray_TypeNumFromName(char const *str)
+ PyArray_ClipmodeConverter(PyObject *object, NPY_CLIPMODE *val)
+Convert an object to NPY_RAISE / NPY_CLIP / NPY_WRAP
+ PyArray_OutputConverter(PyObject *object, PyArrayObject **address)
+Useful to pass as converter function for O& processing in
+PyArgs_ParseTuple for output arrays
+ PyArray_BroadcastToShape(PyObject *obj, npy_intp *dims, int nd)
+Get Iterator broadcast to a particular shape
+ _PyArray_SigintHandler(int signum)
+ void*
+ _PyArray_GetSigintBuf(void )
+ PyArray_DescrAlignConverter(PyObject *obj, PyArray_Descr **at)
+Get type-descriptor from an object forcing alignment if possible
+None goes to DEFAULT type.
+any object with the .fields attribute and/or .itemsize attribute (if the
+.fields attribute does not give the total size -- i.e. a partial record
+naming). If itemsize is given it must be >= size computed from fields
+The .fields attribute must return a convertible dictionary if present.
+Result inherits from NPY_VOID.
+ PyArray_DescrAlignConverter2(PyObject *obj, PyArray_Descr **at)
+None goes to NULL.
+ PyArray_SearchsideConverter(PyObject *obj, void *addr)
+Convert object to searchsorted side
+ PyArray_CheckAxis(PyArrayObject *arr, int *axis, int flags)
+PyArray_CheckAxis
+check that axis is valid
+convert 0-d arrays to 1-d arrays
+ PyArray_OverflowMultiplyList(npy_intp const *l1, int n)
+Multiply a List of Non-negative numbers with over-flow detection.
+ PyArray_CompareString(const char *s1, const char *s2, size_t len)
+ PyArray_MultiIterFromObjects(PyObject **mps, int n, int nadd, ... )
+Get MultiIterator from array of Python objects and any additional
+PyObject **mps - array of PyObjects
+int n - number of PyObjects in the array
+int nadd - number of additional arrays to include in the iterator.
+Returns a multi-iterator object.
+ PyArray_GetEndianness(void )
+ PyArray_GetNDArrayCFeatureVersion(void )
+Returns the built-in (at compilation time) C API version
+ PyArray_Correlate2(PyObject *op1, PyObject *op2, int mode)
+correlate(a1,a2,mode)
+This function computes the usual correlation (correlate(a1, a2) !=
+correlate(a2, a1), and conjugate the second argument for complex inputs
+ PyArray_NeighborhoodIterNew(PyArrayIterObject *x, const npy_intp
+ *bounds, int mode, PyArrayObject*fill)
+A Neighborhood Iterator object.
+ PyArray_SetDatetimeParseFunction(PyObject *NPY_UNUSED(op) )
+This function is scheduled to be removed
+TO BE REMOVED - NOT USED INTERNALLY.
+ PyArray_DatetimeToDatetimeStruct(npy_datetime NPY_UNUSED(val)
+ , NPY_DATETIMEUNIT NPY_UNUSED(fr)
+ , npy_datetimestruct *result)
+Fill the datetime struct from the value and resolution unit.
+ PyArray_TimedeltaToTimedeltaStruct(npy_timedelta NPY_UNUSED(val)
+ , npy_timedeltastruct *result)
+Fill the timedelta struct from the timedelta value and resolution unit.
+ npy_datetime
+ PyArray_DatetimeStructToDatetime(NPY_DATETIMEUNIT NPY_UNUSED(fr)
+ , npy_datetimestruct *NPY_UNUSED(d) )
+Create a datetime value from a filled datetime struct and resolution unit.
+ PyArray_TimedeltaStructToTimedelta(NPY_DATETIMEUNIT NPY_UNUSED(fr)
+ , npy_timedeltastruct
+ *NPY_UNUSED(d) )
+Create a timdelta value from a filled timedelta struct and resolution unit.
+ NpyIter *
+ NpyIter_New(PyArrayObject *op, npy_uint32 flags, NPY_ORDER
+ order, NPY_CASTING casting, PyArray_Descr*dtype)
+Allocate a new iterator for one array object.
+ NpyIter_MultiNew(int nop, PyArrayObject **op_in, npy_uint32
+ flags, NPY_ORDER order, NPY_CASTING
+ casting, npy_uint32 *op_flags, PyArray_Descr
+ **op_request_dtypes)
+Allocate a new iterator for more than one array object, using
+standard NumPy broadcasting rules and the default buffer size.
+ NpyIter_AdvancedNew(int nop, PyArrayObject **op_in, npy_uint32
+ **op_request_dtypes, int oa_ndim, int
+ **op_axes, npy_intp *itershape, npy_intp
+ buffersize)
+Allocate a new iterator for multiple array objects, and advanced
+options for controlling the broadcasting, shape, and buffer size.
+ NpyIter_Copy(NpyIter *iter)
+Makes a copy of the iterator
+ NpyIter_Deallocate(NpyIter *iter)
+Deallocate an iterator.
+To correctly work when an error is in progress, we have to check
+`PyErr_Occurred()`. This is necessary when buffers are not finalized
+or WritebackIfCopy is used. We could avoid that check by exposing a new
+function which is passed in whether or not a Python error is already set.
+ NpyIter_HasDelayedBufAlloc(NpyIter *iter)
+Whether the buffer allocation is being delayed
+ NpyIter_HasExternalLoop(NpyIter *iter)
+Whether the iterator handles the inner loop
+ NpyIter_EnableExternalLoop(NpyIter *iter)
+Removes the inner loop handling (so HasExternalLoop returns true)
+ npy_intp *
+ NpyIter_GetInnerStrideArray(NpyIter *iter)
+Get the array of strides for the inner loop (when HasExternalLoop is true)
+This function may be safely called without holding the Python GIL.
+ NpyIter_GetInnerLoopSizePtr(NpyIter *iter)
+Get a pointer to the size of the inner loop (when HasExternalLoop is true)
+ NpyIter_Reset(NpyIter *iter, char **errmsg)
+Resets the iterator to its initial state
+The use of errmsg is discouraged, it cannot be guaranteed that the GIL
+will not be grabbed on casting errors even when this is passed.
+If errmsg is non-NULL, it should point to a variable which will
+receive the error message, and no Python exception will be set.
+This is so that the function can be called from code not holding
+the GIL. Note that cast errors may still lead to the GIL being
+grabbed temporarily.
+ NpyIter_ResetBasePointers(NpyIter *iter, char **baseptrs, char
+ **errmsg)
+Resets the iterator to its initial state, with new base data pointers.
+This function requires great caution.
+ NpyIter_ResetToIterIndexRange(NpyIter *iter, npy_intp istart, npy_intp
+ iend, char **errmsg)
+Resets the iterator to a new iterator index range
+ NpyIter_GetNDim(NpyIter *iter)
+Gets the number of dimensions being iterated
+ NpyIter_GetNOp(NpyIter *iter)
+Gets the number of operands being iterated
+ NpyIter_IterNextFunc *
+ NpyIter_GetIterNext(NpyIter *iter, char **errmsg)
+Compute the specialized iteration function for an iterator
+the GIL.
+ NpyIter_GetIterSize(NpyIter *iter)
+Gets the number of elements being iterated
+ NpyIter_GetIterIndexRange(NpyIter *iter, npy_intp *istart, npy_intp
+ *iend)
+Gets the range of iteration indices being iterated
+ NpyIter_GetIterIndex(NpyIter *iter)
+Gets the current iteration index
+ NpyIter_GotoIterIndex(NpyIter *iter, npy_intp iterindex)
+Sets the iterator position to the specified iterindex,
+which matches the iteration order of the iterator.
+Returns NPY_SUCCEED on success, NPY_FAIL on failure.
+ NpyIter_HasMultiIndex(NpyIter *iter)
+Whether the iterator is tracking a multi-index
+ NpyIter_GetShape(NpyIter *iter, npy_intp *outshape)
+Gets the broadcast shape if a multi-index is being tracked by the iterator,
+otherwise gets the shape of the iteration as Fortran-order
+(fastest-changing index first).
+The reason Fortran-order is returned when a multi-index
+is not enabled is that this is providing a direct view into how
+the iterator traverses the n-dimensional space. The iterator organizes
+its memory from fastest index to slowest index, and when
+a multi-index is enabled, it uses a permutation to recover the original
+order.
+Returns NPY_SUCCEED or NPY_FAIL.
+ NpyIter_GetMultiIndexFunc *
+ NpyIter_GetGetMultiIndex(NpyIter *iter, char **errmsg)
+Compute a specialized get_multi_index function for the iterator
+ NpyIter_GotoMultiIndex(NpyIter *iter, npy_intp const *multi_index)
+Sets the iterator to the specified multi-index, which must have the
+correct number of entries for 'ndim'. It is only valid
+when NPY_ITER_MULTI_INDEX was passed to the constructor. This operation
+fails if the multi-index is out of bounds.
+ NpyIter_RemoveMultiIndex(NpyIter *iter)
+Removes multi-index support from an iterator.
+ NpyIter_HasIndex(NpyIter *iter)
+Whether the iterator is tracking an index
+ NpyIter_IsBuffered(NpyIter *iter)
+Whether the iterator is buffered
+ NpyIter_IsGrowInner(NpyIter *iter)
+Whether the inner loop can grow if buffering is unneeded
+ NpyIter_GetBufferSize(NpyIter *iter)
+Gets the size of the buffer, or 0 if buffering is not enabled
+ NpyIter_GetIndexPtr(NpyIter *iter)
+Get a pointer to the index, if it is being tracked
+ NpyIter_GotoIndex(NpyIter *iter, npy_intp flat_index)
+If the iterator is tracking an index, sets the iterator
+to the specified index.
+ char **
+ NpyIter_GetDataPtrArray(NpyIter *iter)
+Get the array of data pointers (1 per object being iterated)
+ PyArray_Descr **
+ NpyIter_GetDescrArray(NpyIter *iter)
+Get the array of data type pointers (1 per object being iterated)
+ NpyIter_GetOperandArray(NpyIter *iter)
+Get the array of objects being iterated
+ PyArrayObject *
+ NpyIter_GetIterView(NpyIter *iter, npy_intp i)
+Returns a view to the i-th object with the iterator's internal axes
+ NpyIter_GetReadFlags(NpyIter *iter, char *outreadflags)
+Gets an array of read flags (1 per object being iterated)
+ NpyIter_GetWriteFlags(NpyIter *iter, char *outwriteflags)
+Gets an array of write flags (1 per object being iterated)
+ NpyIter_DebugPrint(NpyIter *iter)
+For debugging
+ NpyIter_IterationNeedsAPI(NpyIter *iter)
+Whether the iteration loop, and in particular the iternext()
+function, needs API access. If this is true, the GIL must
+be retained while iterating.
+ NpyIter_GetInnerFixedStrideArray(NpyIter *iter, npy_intp *out_strides)
+Get an array of strides which are fixed. Any strides which may
+change during iteration receive the value NPY_MAX_INTP. Once
+the iterator is ready to iterate, call this to get the strides
+which will always be fixed in the inner loop, then choose optimized
+inner loop functions which take advantage of those fixed strides.
+ NpyIter_RemoveAxis(NpyIter *iter, int axis)
+Removes an axis from iteration. This requires that NPY_ITER_MULTI_INDEX
+was set for iterator creation, and does not work if buffering is
+enabled. This function also resets the iterator to its initial state.
+ NpyIter_GetAxisStrideArray(NpyIter *iter, int axis)
+Gets the array of strides for the specified axis.
+If the iterator is tracking a multi-index, gets the strides
+for the axis specified, otherwise gets the strides for
+the iteration axis as Fortran order (fastest-changing axis first).
+Returns NULL if an error occurs.
+ NpyIter_RequiresBuffering(NpyIter *iter)
+Whether the iteration could be done with no buffering.
+ NpyIter_GetInitialDataPtrArray(NpyIter *iter)
+Get the array of data pointers (1 per object being iterated),
+directly into the arrays (never pointing to a buffer), for starting
+unbuffered iteration. This always returns the addresses for the
+iterator position as reset to iterator index 0.
+These pointers are different from the pointers accepted by
+NpyIter_ResetBasePointers, because the direction along some
+axes may have been reversed, requiring base offsets.
+ NpyIter_CreateCompatibleStrides(NpyIter *iter, npy_intp
+ itemsize, npy_intp *outstrides)
+Builds a set of strides which are the same as the strides of an
+output array created using the NPY_ITER_ALLOCATE flag, where NULL
+was passed for op_axes. This is for data packed contiguously,
+but not necessarily in C or Fortran order. This should be used
+together with NpyIter_GetShape and NpyIter_GetNDim.
+A use case for this function is to match the shape and layout of
+the iterator and tack on one or more dimensions. For example,
+in order to generate a vector per input value for a numerical gradient,
+you pass in ndim*itemsize for itemsize, then add another dimension to
+the end with size ndim and stride itemsize. To do the Hessian matrix,
+you do the same thing but add two dimensions, or take advantage of
+the symmetry and pack it into 1 dimension with a particular encoding.
+This function may only be called if the iterator is tracking a multi-index
+and if NPY_ITER_DONT_NEGATE_STRIDES was used to prevent an axis from
+being iterated in reverse order.
+If an array is created with this method, simply adding 'itemsize'
+for each iteration will traverse the new array matching the
+iterator.
+ PyArray_CastingConverter(PyObject *obj, NPY_CASTING *casting)
+Convert any Python object, *obj*, to an NPY_CASTING enum.
+ PyArray_CountNonzero(PyArrayObject *self)
+Counts the number of non-zero elements in the array.
+Returns -1 on error.
+ PyArray_PromoteTypes(PyArray_Descr *type1, PyArray_Descr *type2)
+Produces the smallest size and lowest kind type to which both
+input types can be cast.
+ PyArray_MinScalarType(PyArrayObject *arr)
+If arr is a scalar (has 0 dimensions) with a built-in number data type,
+finds the smallest type size/kind which can still represent its data.
+Otherwise, returns the array's data type.
+ PyArray_ResultType(npy_intp narrs, PyArrayObject **arr, npy_intp
+ ndtypes, PyArray_Descr **dtypes)
+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.
+If all the inputs are scalars (have 0 dimensions) or the maximum "kind"
+of the scalars is greater than the maximum "kind" of the arrays, does
+a regular type promotion.
+Otherwise, does a type promotion on the MinScalarType
+of all the inputs. Data types passed directly are treated as array
+types.
+ PyArray_CanCastArrayTo(PyArrayObject *arr, PyArray_Descr
+ *to, NPY_CASTING casting)
+Returns 1 if the array object may be cast to the given data type using
+the casting rule, 0 otherwise. This differs from PyArray_CanCastTo in
+that it handles scalar arrays (0 dimensions) specially, by checking
+their value.
+ PyArray_CanCastTypeTo(PyArray_Descr *from, PyArray_Descr
+Returns true if data of type 'from' may be cast to data of type
+'to' according to the rule 'casting'.
+ PyArray_EinsteinSum(char *subscripts, npy_intp nop, PyArrayObject
+ **op_in, PyArray_Descr *dtype, NPY_ORDER
+ order, NPY_CASTING casting, PyArrayObject *out)
+This function provides summation of array elements according to
+the Einstein summation convention. For example:
+- trace(a) -> einsum("ii", a)
+- transpose(a) -> einsum("ji", a)
+- multiply(a,b) -> einsum(",", a, b)
+- inner(a,b) -> einsum("i,i", a, b)
+- outer(a,b) -> einsum("i,j", a, b)
+- matvec(a,b) -> einsum("ij,j", a, b)
+- matmat(a,b) -> einsum("ij,jk", a, b)
+subscripts: The string of subscripts for einstein summation.
+nop: The number of operands
+op_in: The array of operands
+dtype: Either NULL, or the data type to force the calculation as.
+order: The order for the calculation/the output axes.
+casting: What kind of casts should be permitted.
+out: Either NULL, or an array into which the output should be placed.
+By default, the labels get placed in alphabetical order
+at the end of the output. So, if c = einsum("i,j", a, b)
+then c[i,j] == a[i]*b[j], but if c = einsum("j,i", a, b)
+then c[i,j] = a[j]*b[i].
+Alternatively, you can control the output order or prevent
+an axis from being summed/force an axis to be summed by providing
+indices for the output. This allows us to turn 'trace' into
+'diag', for example.
+- diag(a) -> einsum("ii->i", a)
+- sum(a, axis=0) -> einsum("i...->", a)
+Subscripts at the beginning and end may be specified by
+putting an ellipsis "..." in the middle. For example,
+the function einsum("i...i", a) takes the diagonal of
+the first and last dimensions of the operand, and
+einsum("ij...,jk...->ik...") takes the matrix product using
+the first two indices of each operand instead of the last two.
+When there is only one operand, no axes being summed, and
+no output parameter, this function returns a view
+into the operand instead of making a copy.
+ PyArray_NewLikeArray(PyArrayObject *prototype, NPY_ORDER
+ order, PyArray_Descr *dtype, int subok)
+Creates a new array with the same shape as the provided one,
+with possible memory layout order and data type changes.
+prototype - The array the new one should be like.
+order - NPY_CORDER - C-contiguous result.
+NPY_FORTRANORDER - Fortran-contiguous result.
+NPY_ANYORDER - Fortran if prototype is Fortran, C otherwise.
+NPY_KEEPORDER - Keeps the axis ordering of prototype.
+dtype - If not NULL, overrides the data type of the result.
+subok - If 1, use the prototype's array subtype, otherwise
+always create a base-class array.
+NOTE: If dtype is not NULL, steals the dtype reference. On failure or when
+dtype->subarray is true, dtype will be decrefed.
+ PyArray_GetArrayParamsFromObject(PyObject *NPY_UNUSED(op)
+ , PyArray_Descr
+ *NPY_UNUSED(requested_dtype)
+ , npy_bool NPY_UNUSED(writeable)
+ **NPY_UNUSED(out_dtype) , int
+ *NPY_UNUSED(out_ndim) , npy_intp
+ *NPY_UNUSED(out_dims) , PyArrayObject
+ **NPY_UNUSED(out_arr) , PyObject
+ *NPY_UNUSED(context) )
+ PyArray_ConvertClipmodeSequence(PyObject *object, NPY_CLIPMODE
+ *modes, int n)
+Convert an object to an array of n NPY_CLIPMODE values.
+This is intended to be used in functions where a different mode
+could be applied to each axis, like in ravel_multi_index.
+ PyArray_MatrixProduct2(PyObject *op1, PyObject
+ *op2, PyArrayObject*out)
+Numeric.matrixproduct2(a,v,out)
+ NpyIter_IsFirstVisit(NpyIter *iter, int iop)
+Checks to see whether this is the first time the elements
+of the specified reduction operand which the iterator points at are
+being seen for the first time. The function returns
+a reasonable answer for reduction operands and when buffering is
+disabled. The answer may be incorrect for buffered non-reduction
+operands.
+This function is intended to be used in EXTERNAL_LOOP mode only,
+and will produce some wrong answers when that mode is not enabled.
+If this function returns true, the caller should also
+check the inner loop stride of the operand, because if
+that stride is 0, then only the first element of the innermost
+external loop is being visited for the first time.
+WARNING: For performance reasons, 'iop' is not bounds-checked,
+it is not confirmed that 'iop' is actually a reduction
+operand, and it is not confirmed that EXTERNAL_LOOP
+mode is enabled. These checks are the responsibility of
+the caller, and should be done outside of any inner loops.
+ PyArray_SetBaseObject(PyArrayObject *arr, PyObject *obj)
+Sets the 'base' attribute of the array. This steals a reference
+to 'obj'.
+ PyArray_CreateSortedStridePerm(int ndim, npy_intp const
+ *strides, npy_stride_sort_item
+ *out_strideperm)
+This function populates the first ndim elements
+of strideperm with sorted descending by their absolute values.
+For example, the stride array (4, -2, 12) becomes
+[(2, 12), (0, 4), (1, -2)].
+ PyArray_RemoveAxesInPlace(PyArrayObject *arr, const npy_bool *flags)
+Removes the axes flagged as True from the array,
+modifying it in place. If an axis flagged for removal
+has a shape entry bigger than one, this effectively selects
+index zero for that axis.
+WARNING: If an axis flagged for removal has a shape equal to zero,
+the array will point to invalid memory. The caller must
+validate this!
+If an axis flagged for removal has a shape larger than one,
+the aligned flag (and in the future the contiguous flags),
+may need explicit update.
+(check also NPY_RELAXED_STRIDES_CHECKING)
+For example, this can be used to remove the reduction axes
+from a reduction result once its computation is complete.
+ PyArray_DebugPrint(PyArrayObject *obj)
+Prints the raw data of the ndarray in a form useful for debugging
+low-level C issues.
+ PyArray_FailUnlessWriteable(PyArrayObject *obj, const char *name)
+This function does nothing if obj is writeable, and raises an exception
+(and returns -1) if obj is not writeable. It may also do other
+house-keeping, such as issuing warnings on arrays which are transitioning
+to become views. Always call this function at some point before writing to
+an array.
+'name' is a name for the array, used to give better error
+messages. Something like "assignment destination", "output array", or even
+just "array".
+ PyArray_SetUpdateIfCopyBase(PyArrayObject *arr, PyArrayObject *base)
+Precondition: 'arr' is a copy of 'base' (though possibly with different
+strides, ordering, etc.). This function sets the UPDATEIFCOPY flag and the
+->base pointer on 'arr', so that when 'arr' is destructed, it will copy any
+changes back to 'base'. DEPRECATED, use PyArray_SetWritebackIfCopyBase
+Steals a reference to 'base'.
+ PyDataMem_NEW(size_t size)
+Allocates memory for array data.
+ PyDataMem_FREE(void *ptr)
+Free memory for array data.
+ PyDataMem_RENEW(void *ptr, size_t size)
+Reallocate/resize memory for array data.
+ PyDataMem_EventHookFunc *
+ PyDataMem_SetEventHook(PyDataMem_EventHookFunc *newhook, void
+ *user_data, void **old_data)
+Sets the allocation event hook for numpy array data.
+Takes a PyDataMem_EventHookFunc *, which has the signature:
+void hook(void *old, void *new, size_t size, void *user_data).
+Also takes a void *user_data, and void **old_data.
+Returns a pointer to the previous hook or NULL. If old_data is
+non-NULL, the previous user_data pointer will be copied to it.
+If not NULL, hook will be called at the end of each PyDataMem_NEW/FREE/RENEW:
+result = PyDataMem_NEW(size) -> (*hook)(NULL, result, size, user_data)
+PyDataMem_FREE(ptr) -> (*hook)(ptr, NULL, 0, user_data)
+result = PyDataMem_RENEW(ptr, size) -> (*hook)(ptr, result, size, user_data)
+When the hook is called, the GIL will be held by the calling
+thread. The hook should be written to be reentrant, if it performs
+operations that might cause new allocation events (such as the
+creation/destruction numpy objects, or creating/destroying Python
+objects which might cause a gc)
+ PyArray_MapIterSwapAxes(PyArrayMapIterObject *mit, PyArrayObject
+ **ret, int getmap)
+ PyArray_MapIterArray(PyArrayObject *a, PyObject *index)
+Use advanced indexing to iterate an array.
+ PyArray_MapIterNext(PyArrayMapIterObject *mit)
+This function needs to update the state of the map iterator
+and point mit->dataptr to the memory-location of the next object
+Note that this function never handles an extra operand but provides
+compatibility for an old (exposed) API.
+ PyArray_Partition(PyArrayObject *op, PyArrayObject *ktharray, int
+ axis, NPY_SELECTKIND which)
+Partition an array in-place
+ PyArray_ArgPartition(PyArrayObject *op, PyArrayObject *ktharray, int
+ArgPartition an array
+ PyArray_SelectkindConverter(PyObject *obj, NPY_SELECTKIND *selectkind)
+Convert object to select kind
+ PyDataMem_NEW_ZEROED(size_t size, size_t elsize)
+Allocates zeroed memory for array data.
+ PyArray_CheckAnyScalarExact(PyObject *obj)
+return true an object is exactly a numpy scalar
+ PyArray_MapIterArrayCopyIfOverlap(PyArrayObject *a, PyObject
+ *index, int
+ copy_if_overlap, PyArrayObject
+ *extra_op)
+Same as PyArray_MapIterArray, but:
+If copy_if_overlap != 0, check if `a` has memory overlap with any of the
+arrays in `index` and with `extra_op`. If yes, make copies as appropriate
+to avoid problems if `a` is modified during the iteration.
+`iter->array` may contain a copied array (UPDATEIFCOPY/WRITEBACKIFCOPY set).
+ PyArray_ResolveWritebackIfCopy(PyArrayObject *self)
+If WRITEBACKIFCOPY and self has data, reset the base WRITEABLE flag,
+copy the local data to base, release the local data, and set flags
+appropriately. Return 0 if not relevant, 1 if success, < 0 on failure
+ PyArray_SetWritebackIfCopyBase(PyArrayObject *arr, PyArrayObject
+ *base)
+strides, ordering, etc.). This function sets the WRITEBACKIFCOPY flag and the
+->base pointer on 'arr', call PyArray_ResolveWritebackIfCopy to copy any
+changes back to 'base' before deallocating the array.
@@ -0,0 +1,268 @@
+ * DON'T INCLUDE THIS DIRECTLY.
+#ifndef NPY_NDARRAYOBJECT_H
+#define NPY_NDARRAYOBJECT_H
+#include "ndarraytypes.h"
+/* Includes the "function" C-API -- these are all stored in a
+ list of pointers --- one for each file
+ The two lists are concatenated into one in multiarray.
+ They are available as import_array()
+#include "__multiarray_api.h"
+/* C-API that requires previous API to be defined */
+#define PyArray_DescrCheck(op) PyObject_TypeCheck(op, &PyArrayDescr_Type)
+#define PyArray_Check(op) PyObject_TypeCheck(op, &PyArray_Type)
+#define PyArray_CheckExact(op) (((PyObject*)(op))->ob_type == &PyArray_Type)
+#define PyArray_HasArrayInterfaceType(op, type, context, out) \
+ ((((out)=PyArray_FromStructInterface(op)) != Py_NotImplemented) || \
+ (((out)=PyArray_FromInterface(op)) != Py_NotImplemented) || \
+ (((out)=PyArray_FromArrayAttr(op, type, context)) != \
+ Py_NotImplemented))
+#define PyArray_HasArrayInterface(op, out) \
+ PyArray_HasArrayInterfaceType(op, NULL, NULL, out)
+#define PyArray_IsZeroDim(op) (PyArray_Check(op) && \
+ (PyArray_NDIM((PyArrayObject *)op) == 0))
+#define PyArray_IsScalar(obj, cls) \
+ (PyObject_TypeCheck(obj, &Py##cls##ArrType_Type))
+#define PyArray_CheckScalar(m) (PyArray_IsScalar(m, Generic) || \
+ PyArray_IsZeroDim(m))
+#define PyArray_IsPythonNumber(obj) \
+ (PyFloat_Check(obj) || PyComplex_Check(obj) || \
+ PyLong_Check(obj) || PyBool_Check(obj))
+#define PyArray_IsIntegerScalar(obj) (PyLong_Check(obj) \
+ || PyArray_IsScalar((obj), Integer))
+#define PyArray_IsPythonScalar(obj) \
+ (PyArray_IsPythonNumber(obj) || PyBytes_Check(obj) || \
+ PyUnicode_Check(obj))
+#define PyArray_IsAnyScalar(obj) \
+ (PyArray_IsScalar(obj, Generic) || PyArray_IsPythonScalar(obj))
+#define PyArray_CheckAnyScalar(obj) (PyArray_IsPythonScalar(obj) || \
+ PyArray_CheckScalar(obj))
+#define PyArray_GETCONTIGUOUS(m) (PyArray_ISCONTIGUOUS(m) ? \
+ Py_INCREF(m), (m) : \
+ (PyArrayObject *)(PyArray_Copy(m)))
+#define PyArray_SAMESHAPE(a1,a2) ((PyArray_NDIM(a1) == PyArray_NDIM(a2)) && \
+ PyArray_CompareLists(PyArray_DIMS(a1), \
+ PyArray_DIMS(a2), \
+ PyArray_NDIM(a1)))
+#define PyArray_SIZE(m) PyArray_MultiplyList(PyArray_DIMS(m), PyArray_NDIM(m))
+#define PyArray_NBYTES(m) (PyArray_ITEMSIZE(m) * PyArray_SIZE(m))
+#define PyArray_FROM_O(m) PyArray_FromAny(m, NULL, 0, 0, 0, NULL)
+#define PyArray_FROM_OF(m,flags) PyArray_CheckFromAny(m, NULL, 0, 0, flags, \
+ NULL)
+#define PyArray_FROM_OT(m,type) PyArray_FromAny(m, \
+ PyArray_DescrFromType(type), 0, 0, 0, NULL)
+#define PyArray_FROM_OTF(m, type, flags) \
+ PyArray_FromAny(m, PyArray_DescrFromType(type), 0, 0, \
+ (((flags) & NPY_ARRAY_ENSURECOPY) ? \
+ ((flags) | NPY_ARRAY_DEFAULT) : (flags)), NULL)
+#define PyArray_FROMANY(m, type, min, max, flags) \
+ PyArray_FromAny(m, PyArray_DescrFromType(type), min, max, \
+ (flags) | NPY_ARRAY_DEFAULT : (flags)), NULL)
+#define PyArray_ZEROS(m, dims, type, is_f_order) \
+ PyArray_Zeros(m, dims, PyArray_DescrFromType(type), is_f_order)
+#define PyArray_EMPTY(m, dims, type, is_f_order) \
+ PyArray_Empty(m, dims, PyArray_DescrFromType(type), is_f_order)
+#define PyArray_FILLWBYTE(obj, val) memset(PyArray_DATA(obj), val, \
+ PyArray_NBYTES(obj))
+#ifndef PYPY_VERSION
+#define PyArray_REFCOUNT(obj) (((PyObject *)(obj))->ob_refcnt)
+#define NPY_REFCOUNT PyArray_REFCOUNT
+#define NPY_MAX_ELSIZE (2 * NPY_SIZEOF_LONGDOUBLE)
+#define PyArray_ContiguousFromAny(op, type, min_depth, max_depth) \
+ PyArray_FromAny(op, PyArray_DescrFromType(type), min_depth, \
+ max_depth, NPY_ARRAY_DEFAULT, NULL)
+#define PyArray_EquivArrTypes(a1, a2) \
+ PyArray_EquivTypes(PyArray_DESCR(a1), PyArray_DESCR(a2))
+#define PyArray_EquivByteorders(b1, b2) \
+ (((b1) == (b2)) || (PyArray_ISNBO(b1) == PyArray_ISNBO(b2)))
+#define PyArray_SimpleNew(nd, dims, typenum) \
+ PyArray_New(&PyArray_Type, nd, dims, typenum, NULL, NULL, 0, 0, NULL)
+#define PyArray_SimpleNewFromData(nd, dims, typenum, data) \
+ PyArray_New(&PyArray_Type, nd, dims, typenum, NULL, \
+ data, 0, NPY_ARRAY_CARRAY, NULL)
+#define PyArray_SimpleNewFromDescr(nd, dims, descr) \
+ PyArray_NewFromDescr(&PyArray_Type, descr, nd, dims, \
+ NULL, NULL, 0, NULL)
+#define PyArray_ToScalar(data, arr) \
+ PyArray_Scalar(data, PyArray_DESCR(arr), (PyObject *)arr)
+/* These might be faster without the dereferencing of obj
+ going on inside -- of course an optimizing compiler should
+ inline the constants inside a for loop making it a moot point
+#define PyArray_GETPTR1(obj, i) ((void *)(PyArray_BYTES(obj) + \
+ (i)*PyArray_STRIDES(obj)[0]))
+#define PyArray_GETPTR2(obj, i, j) ((void *)(PyArray_BYTES(obj) + \
+ (i)*PyArray_STRIDES(obj)[0] + \
+ (j)*PyArray_STRIDES(obj)[1]))
+#define PyArray_GETPTR3(obj, i, j, k) ((void *)(PyArray_BYTES(obj) + \
+ (j)*PyArray_STRIDES(obj)[1] + \
+ (k)*PyArray_STRIDES(obj)[2]))
+#define PyArray_GETPTR4(obj, i, j, k, l) ((void *)(PyArray_BYTES(obj) + \
+ (k)*PyArray_STRIDES(obj)[2] + \
+ (l)*PyArray_STRIDES(obj)[3]))
+/* Move to arrayobject.c once PyArray_XDECREF_ERR is removed */
+static NPY_INLINE void
+PyArray_DiscardWritebackIfCopy(PyArrayObject *arr)
+ PyArrayObject_fields *fa = (PyArrayObject_fields *)arr;
+ if (fa && fa->base) {
+ if ((fa->flags & NPY_ARRAY_UPDATEIFCOPY) ||
+ (fa->flags & NPY_ARRAY_WRITEBACKIFCOPY)) {
+ PyArray_ENABLEFLAGS((PyArrayObject*)fa->base, NPY_ARRAY_WRITEABLE);
+ Py_DECREF(fa->base);
+ fa->base = NULL;
+ PyArray_CLEARFLAGS(arr, NPY_ARRAY_WRITEBACKIFCOPY);
+ PyArray_CLEARFLAGS(arr, NPY_ARRAY_UPDATEIFCOPY);
+#define PyArray_DESCR_REPLACE(descr) do { \
+ PyArray_Descr *_new_; \
+ _new_ = PyArray_DescrNew(descr); \
+ Py_XDECREF(descr); \
+ descr = _new_; \
+/* Copy should always return contiguous array */
+#define PyArray_Copy(obj) PyArray_NewCopy(obj, NPY_CORDER)
+#define PyArray_FromObject(op, type, min_depth, max_depth) \
+ max_depth, NPY_ARRAY_BEHAVED | \
+ NPY_ARRAY_ENSUREARRAY, NULL)
+#define PyArray_ContiguousFromObject(op, type, min_depth, max_depth) \
+ max_depth, NPY_ARRAY_DEFAULT | \
+#define PyArray_CopyFromObject(op, type, min_depth, max_depth) \
+ max_depth, NPY_ARRAY_ENSURECOPY | \
+ NPY_ARRAY_DEFAULT | \
+#define PyArray_Cast(mp, type_num) \
+ PyArray_CastToType(mp, PyArray_DescrFromType(type_num), 0)
+#define PyArray_Take(ap, items, axis) \
+ PyArray_TakeFrom(ap, items, axis, NULL, NPY_RAISE)
+#define PyArray_Put(ap, items, values) \
+ PyArray_PutTo(ap, items, values, NPY_RAISE)
+/* Compatibility with old Numeric stuff -- don't use in new code */
+#define PyArray_FromDimsAndData(nd, d, type, data) \
+ PyArray_FromDimsAndDataAndDescr(nd, d, PyArray_DescrFromType(type), \
+ data)
+ Check to see if this key in the dictionary is the "title"
+ entry of the tuple (i.e. a duplicate dictionary entry in the fields
+ dict).
+NPY_TITLE_KEY_check(PyObject *key, PyObject *value)
+ PyObject *title;
+ if (PyTuple_Size(value) != 3) {
+ title = PyTuple_GetItem(value, 2);
+ if (key == title) {
+ return 1;
+#ifdef PYPY_VERSION
+ * On PyPy, dictionary keys do not always preserve object identity.
+ * Fall back to comparison by value.
+ if (PyUnicode_Check(title) && PyUnicode_Check(key)) {
+ return PyUnicode_Compare(title, key) == 0 ? 1 : 0;
+/* Macro, for backward compat with "if NPY_TITLE_KEY(key, value) { ..." */
+#define NPY_TITLE_KEY(key, value) (NPY_TITLE_KEY_check((key), (value)))
+#define DEPRECATE(msg) PyErr_WarnEx(PyExc_DeprecationWarning,msg,1)
+#define DEPRECATE_FUTUREWARNING(msg) PyErr_WarnEx(PyExc_FutureWarning,msg,1)
+#if !defined(NPY_NO_DEPRECATED_API) || \
+ (NPY_NO_DEPRECATED_API < NPY_1_14_API_VERSION)
+PyArray_XDECREF_ERR(PyArrayObject *arr)
+ /* 2017-Nov-10 1.14 */
+ DEPRECATE("PyArray_XDECREF_ERR is deprecated, call "
+ "PyArray_DiscardWritebackIfCopy then Py_XDECREF instead");
+ PyArray_DiscardWritebackIfCopy(arr);
+ Py_XDECREF(arr);
+#endif /* NPY_NDARRAYOBJECT_H */
@@ -0,0 +1,1960 @@
+#ifndef NDARRAYTYPES_H
+#define NDARRAYTYPES_H
+#include "npy_common.h"
+#include "npy_endian.h"
+#include "npy_cpu.h"
+#include "utils.h"
+#define NPY_NO_EXPORT NPY_VISIBILITY_HIDDEN
+/* Only use thread if configured in config and python supports it */
+#if defined WITH_THREAD && !NPY_NO_SMP
+ #define NPY_ALLOW_THREADS 1
+ #define NPY_ALLOW_THREADS 0
+#ifndef __has_extension
+#define __has_extension(x) 0
+#if !defined(_NPY_NO_DEPRECATIONS) && \
+ ((defined(__GNUC__)&& __GNUC__ >= 6) || \
+ __has_extension(attribute_deprecated_with_message))
+#define NPY_ATTR_DEPRECATE(text) __attribute__ ((deprecated (text)))
+#define NPY_ATTR_DEPRECATE(text)
+ * There are several places in the code where an array of dimensions
+ * is allocated statically. This is the size of that static
+ * allocation.
+ * The array creation itself could have arbitrary dimensions but all
+ * the places where static allocation is used would need to be changed
+ * to dynamic (including inside of several structures)
+#define NPY_MAXDIMS 32
+#define NPY_MAXARGS 32
+/* Used for Converter Functions "O&" code in ParseTuple */
+#define NPY_FAIL 0
+#define NPY_SUCCEED 1
+ * Binary compatibility version number. This number is increased
+ * whenever the C-API is changed such that binary compatibility is
+ * broken, i.e. whenever a recompile of extension modules is needed.
+#define NPY_VERSION NPY_ABI_VERSION
+ * Minor API version. This number is increased whenever a change is
+ * made to the C-API -- whether it breaks binary compatibility or not.
+ * Some changes, such as adding a function pointer to the end of the
+ * function table, can be made without breaking binary compatibility.
+ * In this case, only the NPY_FEATURE_VERSION (*not* NPY_VERSION)
+ * would be increased. Whenever binary compatibility is broken, both
+ * NPY_VERSION and NPY_FEATURE_VERSION should be increased.
+#define NPY_FEATURE_VERSION NPY_API_VERSION
+enum NPY_TYPES { NPY_BOOL=0,
+ NPY_BYTE, NPY_UBYTE,
+ NPY_SHORT, NPY_USHORT,
+ NPY_INT, NPY_UINT,
+ NPY_LONG, NPY_ULONG,
+ NPY_LONGLONG, NPY_ULONGLONG,
+ NPY_FLOAT, NPY_DOUBLE, NPY_LONGDOUBLE,
+ NPY_CFLOAT, NPY_CDOUBLE, NPY_CLONGDOUBLE,
+ NPY_OBJECT=17,
+ NPY_STRING, NPY_UNICODE,
+ NPY_VOID,
+ * New 1.6 types appended, may be integrated
+ * into the above in 2.0.
+ NPY_DATETIME, NPY_TIMEDELTA, NPY_HALF,
+ NPY_NTYPES,
+ NPY_NOTYPE,
+ NPY_CHAR NPY_ATTR_DEPRECATE("Use NPY_STRING"),
+ NPY_USERDEF=256, /* leave room for characters */
+ /* The number of types not including the new 1.6 types */
+ NPY_NTYPES_ABI_COMPATIBLE=21
+#ifdef _MSC_VER
+#pragma deprecated(NPY_CHAR)
+/* basetype array priority */
+#define NPY_PRIORITY 0.0
+/* default subtype priority */
+#define NPY_SUBTYPE_PRIORITY 1.0
+/* default scalar priority */
+#define NPY_SCALAR_PRIORITY -1000000.0
+/* How many floating point types are there (excluding half) */
+#define NPY_NUM_FLOATTYPE 3
+ * These characters correspond to the array type and the struct
+ * module
+enum NPY_TYPECHAR {
+ NPY_BOOLLTR = '?',
+ NPY_BYTELTR = 'b',
+ NPY_UBYTELTR = 'B',
+ NPY_SHORTLTR = 'h',
+ NPY_USHORTLTR = 'H',
+ NPY_INTLTR = 'i',
+ NPY_UINTLTR = 'I',
+ NPY_LONGLTR = 'l',
+ NPY_ULONGLTR = 'L',
+ NPY_LONGLONGLTR = 'q',
+ NPY_ULONGLONGLTR = 'Q',
+ NPY_HALFLTR = 'e',
+ NPY_FLOATLTR = 'f',
+ NPY_DOUBLELTR = 'd',
+ NPY_LONGDOUBLELTR = 'g',
+ NPY_CFLOATLTR = 'F',
+ NPY_CDOUBLELTR = 'D',
+ NPY_CLONGDOUBLELTR = 'G',
+ NPY_OBJECTLTR = 'O',
+ NPY_STRINGLTR = 'S',
+ NPY_STRINGLTR2 = 'a',
+ NPY_UNICODELTR = 'U',
+ NPY_VOIDLTR = 'V',
+ NPY_DATETIMELTR = 'M',
+ NPY_TIMEDELTALTR = 'm',
+ NPY_CHARLTR = 'c',
+ * No Descriptor, just a define -- this let's
+ * Python users specify an array of integers
+ * large enough to hold a pointer on the
+ * platform
+ NPY_INTPLTR = 'p',
+ NPY_UINTPLTR = 'P',
+ * These are for dtype 'kinds', not dtype 'typecodes'
+ * as the above are for.
+ NPY_GENBOOLLTR ='b',
+ NPY_SIGNEDLTR = 'i',
+ NPY_UNSIGNEDLTR = 'u',
+ NPY_FLOATINGLTR = 'f',
+ NPY_COMPLEXLTR = 'c'
+ * Changing this may break Numpy API compatibility
+ * due to changing offsets in PyArray_ArrFuncs, so be
+ * careful. Here we have reused the mergesort slot for
+ * any kind of stable sort, the actual implementation will
+ * depend on the data type.
+typedef enum {
+ NPY_QUICKSORT=0,
+ NPY_HEAPSORT=1,
+ NPY_MERGESORT=2,
+ NPY_STABLESORT=2,
+} NPY_SORTKIND;
+#define NPY_NSORTS (NPY_STABLESORT + 1)
+ NPY_INTROSELECT=0
+} NPY_SELECTKIND;
+#define NPY_NSELECTS (NPY_INTROSELECT + 1)
+ NPY_SEARCHLEFT=0,
+ NPY_SEARCHRIGHT=1
+} NPY_SEARCHSIDE;
+#define NPY_NSEARCHSIDES (NPY_SEARCHRIGHT + 1)
+ NPY_NOSCALAR=-1,
+} NPY_SCALARKIND;
+#define NPY_NSCALARKINDS (NPY_OBJECT_SCALAR + 1)
+/* For specifying array memory layout or iteration order */
+ /* Fortran order if inputs are all Fortran, C otherwise */
+ NPY_ANYORDER=-1,
+ /* C order */
+ NPY_CORDER=0,
+ /* Fortran order */
+ NPY_FORTRANORDER=1,
+ /* An order as close to the inputs as possible */
+ NPY_KEEPORDER=2
+} NPY_ORDER;
+/* For specifying allowed casting in operations which support it */
+ _NPY_ERROR_OCCURRED_IN_CAST = -1,
+ /* Only allow identical types */
+ NPY_NO_CASTING=0,
+ /* Allow identical and byte swapped types */
+ NPY_EQUIV_CASTING=1,
+ /* Only allow safe casts */
+ NPY_SAFE_CASTING=2,
+ /* Allow safe casts or casts within the same kind */
+ NPY_SAME_KIND_CASTING=3,
+ /* Allow any casts */
+ NPY_UNSAFE_CASTING=4,
+ * Flag to allow signalling that a cast is a view, this flag is not
+ * valid when requesting a cast of specific safety.
+ * _NPY_CAST_IS_VIEW|NPY_EQUIV_CASTING means the same as NPY_NO_CASTING.
+ // TODO-DTYPES: Needs to be documented.
+ _NPY_CAST_IS_VIEW = 1 << 16,
+} NPY_CASTING;
+ NPY_CLIP=0,
+ NPY_WRAP=1,
+ NPY_RAISE=2
+} NPY_CLIPMODE;
+/* The special not-a-time (NaT) value */
+#define NPY_DATETIME_NAT NPY_MIN_INT64
+ * Upper bound on the length of a DATETIME ISO 8601 string
+ * YEAR: 21 (64-bit year)
+ * MONTH: 3
+ * DAY: 3
+ * HOURS: 3
+ * MINUTES: 3
+ * SECONDS: 3
+ * ATTOSECONDS: 1 + 3*6
+ * TIMEZONE: 5
+ * NULL TERMINATOR: 1
+#define NPY_DATETIME_MAX_ISO8601_STRLEN (21 + 3*5 + 1 + 3*6 + 6 + 1)
+/* The FR in the unit names stands for frequency */
+ /* Force signed enum type, must be -1 for code compatibility */
+ NPY_FR_ERROR = -1, /* error or undetermined */
+ /* Start of valid units */
+ NPY_FR_Y = 0, /* Years */
+ NPY_FR_M = 1, /* Months */
+ NPY_FR_W = 2, /* Weeks */
+ /* Gap where 1.6 NPY_FR_B (value 3) was */
+ NPY_FR_D = 4, /* Days */
+ NPY_FR_h = 5, /* hours */
+ NPY_FR_m = 6, /* minutes */
+ NPY_FR_s = 7, /* seconds */
+ NPY_FR_ms = 8, /* milliseconds */
+ NPY_FR_us = 9, /* microseconds */
+ NPY_FR_ns = 10, /* nanoseconds */
+ NPY_FR_ps = 11, /* picoseconds */
+ NPY_FR_fs = 12, /* femtoseconds */
+ NPY_FR_as = 13, /* attoseconds */
+ NPY_FR_GENERIC = 14 /* unbound units, can convert to anything */
+} NPY_DATETIMEUNIT;
+ * NOTE: With the NPY_FR_B gap for 1.6 ABI compatibility, NPY_DATETIME_NUMUNITS
+ * is technically one more than the actual number of units.
+#define NPY_DATETIME_NUMUNITS (NPY_FR_GENERIC + 1)
+#define NPY_DATETIME_DEFAULTUNIT NPY_FR_GENERIC
+ * Business day conventions for mapping invalid business
+ * days to valid business days.
+ /* Go forward in time to the following business day. */
+ NPY_BUSDAY_FORWARD,
+ NPY_BUSDAY_FOLLOWING = NPY_BUSDAY_FORWARD,
+ /* Go backward in time to the preceding business day. */
+ NPY_BUSDAY_BACKWARD,
+ NPY_BUSDAY_PRECEDING = NPY_BUSDAY_BACKWARD,
+ * Go forward in time to the following business day, unless it
+ * crosses a month boundary, in which case go backward
+ NPY_BUSDAY_MODIFIEDFOLLOWING,
+ * Go backward in time to the preceding business day, unless it
+ * crosses a month boundary, in which case go forward.
+ NPY_BUSDAY_MODIFIEDPRECEDING,
+ /* Produce a NaT for non-business days. */
+ NPY_BUSDAY_NAT,
+ /* Raise an exception for non-business days. */
+ NPY_BUSDAY_RAISE
+} NPY_BUSDAY_ROLL;
+/************************************************************
+ * NumPy Auxiliary Data for inner loops, sort functions, etc.
+ ************************************************************/
+ * When creating an auxiliary data struct, this should always appear
+ * as the first member, like this:
+ * typedef struct {
+ * NpyAuxData base;
+ * double constant;
+ * } constant_multiplier_aux_data;
+typedef struct NpyAuxData_tag NpyAuxData;
+/* Function pointers for freeing or cloning auxiliary data */
+typedef void (NpyAuxData_FreeFunc) (NpyAuxData *);
+typedef NpyAuxData *(NpyAuxData_CloneFunc) (NpyAuxData *);
+struct NpyAuxData_tag {
+ NpyAuxData_FreeFunc *free;
+ NpyAuxData_CloneFunc *clone;
+ /* To allow for a bit of expansion without breaking the ABI */
+ void *reserved[2];
+/* Macros to use for freeing and cloning auxiliary data */
+#define NPY_AUXDATA_FREE(auxdata) \
+ do { \
+ if ((auxdata) != NULL) { \
+ (auxdata)->free(auxdata); \
+#define NPY_AUXDATA_CLONE(auxdata) \
+ ((auxdata)->clone(auxdata))
+#define NPY_ERR(str) fprintf(stderr, #str); fflush(stderr);
+#define NPY_ERR2(str) fprintf(stderr, str); fflush(stderr);
+ * Macros to define how array, and dimension/strides data is
+ * allocated.
+ /* Data buffer - PyDataMem_NEW/FREE/RENEW are in multiarraymodule.c */
+#define NPY_USE_PYMEM 1
+#if NPY_USE_PYMEM == 1
+/* use the Raw versions which are safe to call with the GIL released */
+#define PyArray_malloc PyMem_RawMalloc
+#define PyArray_free PyMem_RawFree
+#define PyArray_realloc PyMem_RawRealloc
+#define PyArray_malloc malloc
+#define PyArray_free free
+#define PyArray_realloc realloc
+/* Dimensions and strides */
+#define PyDimMem_NEW(size) \
+ ((npy_intp *)PyArray_malloc(size*sizeof(npy_intp)))
+#define PyDimMem_FREE(ptr) PyArray_free(ptr)
+#define PyDimMem_RENEW(ptr,size) \
+ ((npy_intp *)PyArray_realloc(ptr,size*sizeof(npy_intp)))
+/* forward declaration */
+struct _PyArray_Descr;
+/* These must deal with unaligned and swapped data if necessary */
+typedef PyObject * (PyArray_GetItemFunc) (void *, void *);
+typedef int (PyArray_SetItemFunc)(PyObject *, void *, void *);
+typedef void (PyArray_CopySwapNFunc)(void *, npy_intp, void *, npy_intp,
+ npy_intp, int, void *);
+typedef void (PyArray_CopySwapFunc)(void *, void *, int, void *);
+typedef npy_bool (PyArray_NonzeroFunc)(void *, void *);
+ * These assume aligned and notswapped data -- a buffer will be used
+ * before or contiguous data will be obtained
+typedef int (PyArray_CompareFunc)(const void *, const void *, void *);
+typedef int (PyArray_ArgFunc)(void*, npy_intp, npy_intp*, void *);
+typedef void (PyArray_DotFunc)(void *, npy_intp, void *, npy_intp, void *,
+ npy_intp, void *);
+typedef void (PyArray_VectorUnaryFunc)(void *, void *, npy_intp, void *,
+ void *);
+ * XXX the ignore argument should be removed next time the API version
+ * is bumped. It used to be the separator.
+typedef int (PyArray_ScanFunc)(FILE *fp, void *dptr,
+ char *ignore, struct _PyArray_Descr *);
+typedef int (PyArray_FromStrFunc)(char *s, void *dptr, char **endptr,
+ struct _PyArray_Descr *);
+typedef int (PyArray_FillFunc)(void *, npy_intp, void *);
+typedef int (PyArray_SortFunc)(void *, npy_intp, void *);
+typedef int (PyArray_ArgSortFunc)(void *, npy_intp *, npy_intp, void *);
+typedef int (PyArray_PartitionFunc)(void *, npy_intp, npy_intp,
+ npy_intp *, npy_intp *,
+typedef int (PyArray_ArgPartitionFunc)(void *, npy_intp *, npy_intp, npy_intp,
+typedef int (PyArray_FillWithScalarFunc)(void *, npy_intp, void *, void *);
+typedef int (PyArray_ScalarKindFunc)(void *);
+typedef void (PyArray_FastClipFunc)(void *in, npy_intp n_in, void *min,
+ void *max, void *out);
+typedef void (PyArray_FastPutmaskFunc)(void *in, void *mask, npy_intp n_in,
+ void *values, npy_intp nv);
+typedef int (PyArray_FastTakeFunc)(void *dest, void *src, npy_intp *indarray,
+ npy_intp nindarray, npy_intp n_outer,
+ npy_intp m_middle, npy_intp nelem,
+ NPY_CLIPMODE clipmode);
+ npy_intp *ptr;
+ int len;
+} PyArray_Dims;
+ * Functions to cast to most other standard types
+ * Can have some NULL entries. The types
+ * DATETIME, TIMEDELTA, and HALF go into the castdict
+ * even though they are built-in.
+ PyArray_VectorUnaryFunc *cast[NPY_NTYPES_ABI_COMPATIBLE];
+ /* The next four functions *cannot* be NULL */
+ * Functions to get and set items with standard Python types
+ * -- not array scalars
+ PyArray_GetItemFunc *getitem;
+ PyArray_SetItemFunc *setitem;
+ * Copy and/or swap data. Memory areas may not overlap
+ * Use memmove first if they might
+ PyArray_CopySwapNFunc *copyswapn;
+ PyArray_CopySwapFunc *copyswap;
+ * Function to compare items
+ * Can be NULL
+ PyArray_CompareFunc *compare;
+ * Function to select largest
+ PyArray_ArgFunc *argmax;
+ * Function to compute dot product
+ PyArray_DotFunc *dotfunc;
+ * Function to scan an ASCII file and
+ * place a single value plus possible separator
+ PyArray_ScanFunc *scanfunc;
+ * Function to read a single value from a string
+ * and adjust the pointer; Can be NULL
+ PyArray_FromStrFunc *fromstr;
+ * Function to determine if data is zero or not
+ * If NULL a default version is
+ * used at Registration time.
+ PyArray_NonzeroFunc *nonzero;
+ * Used for arange. Should return 0 on success
+ * and -1 on failure.
+ * Can be NULL.
+ PyArray_FillFunc *fill;
+ * Function to fill arrays with scalar values
+ PyArray_FillWithScalarFunc *fillwithscalar;
+ * Sorting functions
+ PyArray_SortFunc *sort[NPY_NSORTS];
+ PyArray_ArgSortFunc *argsort[NPY_NSORTS];
+ * Dictionary of additional casting functions
+ * PyArray_VectorUnaryFuncs
+ * which can be populated to support casting
+ * to other registered types. Can be NULL
+ PyObject *castdict;
+ * Functions useful for generalizing
+ * the casting rules.
+ * Can be NULL;
+ PyArray_ScalarKindFunc *scalarkind;
+ int **cancastscalarkindto;
+ int *cancastto;
+ PyArray_FastClipFunc *fastclip;
+ PyArray_FastPutmaskFunc *fastputmask;
+ PyArray_FastTakeFunc *fasttake;
+ * Function to select smallest
+ PyArray_ArgFunc *argmin;
+} PyArray_ArrFuncs;
+/* The item must be reference counted when it is inserted or extracted. */
+#define NPY_ITEM_REFCOUNT 0x01
+/* Same as needing REFCOUNT */
+#define NPY_ITEM_HASOBJECT 0x01
+/* Convert to list for pickling */
+#define NPY_LIST_PICKLE 0x02
+/* The item is a POINTER */
+#define NPY_ITEM_IS_POINTER 0x04
+/* memory needs to be initialized for this data-type */
+#define NPY_NEEDS_INIT 0x08
+/* operations need Python C-API so don't give-up thread. */
+#define NPY_NEEDS_PYAPI 0x10
+/* Use f.getitem when extracting elements of this data-type */
+#define NPY_USE_GETITEM 0x20
+/* Use f.setitem when setting creating 0-d array from this data-type.*/
+#define NPY_USE_SETITEM 0x40
+/* A sticky flag specifically for structured arrays */
+#define NPY_ALIGNED_STRUCT 0x80
+ *These are inherited for global data-type if any data-types in the
+ * field have them
+#define NPY_FROM_FIELDS (NPY_NEEDS_INIT | NPY_LIST_PICKLE | \
+ NPY_ITEM_REFCOUNT | NPY_NEEDS_PYAPI)
+#define NPY_OBJECT_DTYPE_FLAGS (NPY_LIST_PICKLE | NPY_USE_GETITEM | \
+ NPY_ITEM_IS_POINTER | NPY_ITEM_REFCOUNT | \
+ NPY_NEEDS_INIT | NPY_NEEDS_PYAPI)
+#define PyDataType_FLAGCHK(dtype, flag) \
+ (((dtype)->flags & (flag)) == (flag))
+#define PyDataType_REFCHK(dtype) \
+ PyDataType_FLAGCHK(dtype, NPY_ITEM_REFCOUNT)
+typedef struct _PyArray_Descr {
+ * the type object representing an
+ * instance of this type -- should not
+ * be two type_numbers with the same type
+ * object.
+ PyTypeObject *typeobj;
+ /* kind for this type */
+ char kind;
+ /* unique-character representing this type */
+ char type;
+ * '>' (big), '<' (little), '|'
+ * (not-applicable), or '=' (native).
+ char byteorder;
+ /* flags describing data type */
+ char flags;
+ /* number representing this type */
+ int type_num;
+ /* element size (itemsize) for this type */
+ int elsize;
+ /* alignment needed for this type */
+ int alignment;
+ * Non-NULL if this type is
+ * is an array (C-contiguous)
+ * of some other type
+ struct _arr_descr *subarray;
+ * The fields dictionary for this type
+ * For statically defined descr this
+ * is always Py_None
+ PyObject *fields;
+ * An ordered tuple of field names or NULL
+ * if no fields are defined
+ PyObject *names;
+ * a table of functions specific for each
+ * basic data descriptor
+ PyArray_ArrFuncs *f;
+ /* Metadata about this dtype */
+ PyObject *metadata;
+ * Metadata specific to the C implementation
+ * of the particular dtype. This was added
+ * for NumPy 1.7.0.
+ NpyAuxData *c_metadata;
+ /* Cached hash value (-1 if not yet computed).
+ * This was added for NumPy 2.0.0.
+ npy_hash_t hash;
+} PyArray_Descr;
+typedef struct _arr_descr {
+ PyArray_Descr *base;
+ PyObject *shape; /* a tuple */
+} PyArray_ArrayDescr;
+ * The main array object structure.
+ * It has been recommended to use the inline functions defined below
+ * (PyArray_DATA and friends) to access fields here for a number of
+ * releases. Direct access to the members themselves is deprecated.
+ * To ensure that your code does not use deprecated access,
+ * #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
+ * (or NPY_1_8_API_VERSION or higher as required).
+/* This struct will be moved to a private header in a future release */
+typedef struct tagPyArrayObject_fields {
+ /* Pointer to the raw data buffer */
+ char *data;
+ /* The number of dimensions, also called 'ndim' */
+ int nd;
+ /* The size in each dimension, also called 'shape' */
+ npy_intp *dimensions;
+ * Number of bytes to jump to get to the
+ * next element in each dimension
+ npy_intp *strides;
+ * This object is decref'd upon
+ * deletion of array. Except in the
+ * case of WRITEBACKIFCOPY which has
+ * special handling.
+ * For views it points to the original
+ * array, collapsed so no chains of
+ * views occur.
+ * For creation from buffer object it
+ * points to an object that should be
+ * decref'd on deletion
+ * For WRITEBACKIFCOPY flag this is an
+ * array to-be-updated upon calling
+ * PyArray_ResolveWritebackIfCopy
+ /* Pointer to type structure */
+ /* Flags describing array -- see below */
+ /* For weak references */
+ PyObject *weakreflist;
+} PyArrayObject_fields;
+ * To hide the implementation details, we only expose
+ * the Python struct HEAD.
+ (NPY_NO_DEPRECATED_API < NPY_1_7_API_VERSION)
+ * Can't put this in npy_deprecated_api.h like the others.
+ * PyArrayObject field access is deprecated as of NumPy 1.7.
+typedef PyArrayObject_fields PyArrayObject;
+typedef struct tagPyArrayObject {
+} PyArrayObject;
+ * Removed 2020-Nov-25, NumPy 1.20
+ * #define NPY_SIZEOF_PYARRAYOBJECT (sizeof(PyArrayObject_fields))
+ * The above macro was removed as it gave a false sense of a stable ABI
+ * with respect to the structures size. If you require a runtime constant,
+ * you can use `PyArray_Type.tp_basicsize` instead. Otherwise, please
+ * see the PyArrayObject documentation or ask the NumPy developers for
+ * information on how to correctly replace the macro in a way that is
+ * compatible with multiple NumPy versions.
+/* Array Flags Object */
+typedef struct PyArrayFlagsObject {
+ PyObject *arr;
+} PyArrayFlagsObject;
+/* Mirrors buffer object to ptr */
+ void *ptr;
+ npy_intp len;
+} PyArray_Chunk;
+ NPY_DATETIMEUNIT base;
+ int num;
+} PyArray_DatetimeMetaData;
+ NpyAuxData base;
+ PyArray_DatetimeMetaData meta;
+} PyArray_DatetimeDTypeMetaData;
+ * This structure contains an exploded view of a date-time value.
+ * NaT is represented by year == NPY_DATETIME_NAT.
+ npy_int64 year;
+ npy_int32 month, day, hour, min, sec, us, ps, as;
+} npy_datetimestruct;
+/* This is not used internally. */
+ npy_int64 day;
+ npy_int32 sec, us, ps, as;
+} npy_timedeltastruct;
+typedef int (PyArray_FinalizeFunc)(PyArrayObject *, PyObject *);
+ * Means c-style contiguous (last index varies the fastest). The data
+ * elements right after each other.
+ * This flag may be requested in constructor functions.
+ * This flag may be tested for in PyArray_FLAGS(arr).
+#define NPY_ARRAY_C_CONTIGUOUS 0x0001
+ * Set if array is a contiguous Fortran array: the first index varies
+ * the fastest in memory (strides array is reverse of C-contiguous
+ * array)
+#define NPY_ARRAY_F_CONTIGUOUS 0x0002
+ * Note: all 0-d arrays are C_CONTIGUOUS and F_CONTIGUOUS. If a
+ * 1-d array is C_CONTIGUOUS it is also F_CONTIGUOUS. Arrays with
+ * more then one dimension can be C_CONTIGUOUS and F_CONTIGUOUS
+ * at the same time if they have either zero or one element.
+ * If NPY_RELAXED_STRIDES_CHECKING is set, a higher dimensional
+ * array is always C_CONTIGUOUS and F_CONTIGUOUS if it has zero elements
+ * and the array is contiguous if ndarray.squeeze() is contiguous.
+ * I.e. dimensions for which `ndarray.shape[dimension] == 1` are
+ * ignored.
+ * If set, the array owns the data: it will be free'd when the array
+ * is deleted.
+#define NPY_ARRAY_OWNDATA 0x0004
+ * An array never has the next four set; they're only used as parameter
+ * flags to the various FromAny functions
+/* Cause a cast to occur regardless of whether or not it is safe. */
+#define NPY_ARRAY_FORCECAST 0x0010
+ * Always copy the array. Returned arrays are always CONTIGUOUS,
+ * ALIGNED, and WRITEABLE.
+#define NPY_ARRAY_ENSURECOPY 0x0020
+ * Make sure the returned array is a base-class ndarray
+#define NPY_ARRAY_ENSUREARRAY 0x0040
+ * Make sure that the strides are in units of the element size Needed
+ * for some operations with record-arrays.
+#define NPY_ARRAY_ELEMENTSTRIDES 0x0080
+ * Array data is aligned on the appropriate memory address for the type
+ * stored according to how the compiler would align things (e.g., an
+ * array of integers (4 bytes each) starts on a memory address that's
+ * a multiple of 4)
+#define NPY_ARRAY_ALIGNED 0x0100
+ * Array data has the native endianness
+#define NPY_ARRAY_NOTSWAPPED 0x0200
+ * Array data is writeable
+#define NPY_ARRAY_WRITEABLE 0x0400
+ * If this flag is set, then base contains a pointer to an array of
+ * the same size that should be updated with the current contents of
+ * this array when PyArray_ResolveWritebackIfCopy is called.
+#define NPY_ARRAY_UPDATEIFCOPY 0x1000 /* Deprecated in 1.14 */
+#define NPY_ARRAY_WRITEBACKIFCOPY 0x2000
+ * NOTE: there are also internal flags defined in multiarray/arrayobject.h,
+ * which start at bit 31 and work down.
+#define NPY_ARRAY_BEHAVED (NPY_ARRAY_ALIGNED | \
+ NPY_ARRAY_WRITEABLE)
+#define NPY_ARRAY_BEHAVED_NS (NPY_ARRAY_ALIGNED | \
+ NPY_ARRAY_WRITEABLE | \
+ NPY_ARRAY_NOTSWAPPED)
+#define NPY_ARRAY_CARRAY (NPY_ARRAY_C_CONTIGUOUS | \
+ NPY_ARRAY_BEHAVED)
+#define NPY_ARRAY_CARRAY_RO (NPY_ARRAY_C_CONTIGUOUS | \
+ NPY_ARRAY_ALIGNED)
+#define NPY_ARRAY_FARRAY (NPY_ARRAY_F_CONTIGUOUS | \
+#define NPY_ARRAY_FARRAY_RO (NPY_ARRAY_F_CONTIGUOUS | \
+#define NPY_ARRAY_DEFAULT (NPY_ARRAY_CARRAY)
+#define NPY_ARRAY_IN_ARRAY (NPY_ARRAY_CARRAY_RO)
+#define NPY_ARRAY_OUT_ARRAY (NPY_ARRAY_CARRAY)
+#define NPY_ARRAY_INOUT_ARRAY (NPY_ARRAY_CARRAY | \
+ NPY_ARRAY_UPDATEIFCOPY)
+#define NPY_ARRAY_INOUT_ARRAY2 (NPY_ARRAY_CARRAY | \
+ NPY_ARRAY_WRITEBACKIFCOPY)
+#define NPY_ARRAY_IN_FARRAY (NPY_ARRAY_FARRAY_RO)
+#define NPY_ARRAY_OUT_FARRAY (NPY_ARRAY_FARRAY)
+#define NPY_ARRAY_INOUT_FARRAY (NPY_ARRAY_FARRAY | \
+#define NPY_ARRAY_INOUT_FARRAY2 (NPY_ARRAY_FARRAY | \
+#define NPY_ARRAY_UPDATE_ALL (NPY_ARRAY_C_CONTIGUOUS | \
+ NPY_ARRAY_F_CONTIGUOUS | \
+/* This flag is for the array interface, not PyArrayObject */
+#define NPY_ARR_HAS_DESCR 0x0800
+ * Size of internal buffers used for alignment Make BUFSIZE a multiple
+ * of sizeof(npy_cdouble) -- usually 16 so that ufunc buffers are aligned
+#define NPY_MIN_BUFSIZE ((int)sizeof(npy_cdouble))
+#define NPY_MAX_BUFSIZE (((int)sizeof(npy_cdouble))*1000000)
+#define NPY_BUFSIZE 8192
+/* buffer stress test size: */
+/*#define NPY_BUFSIZE 17*/
+#define PyArray_MAX(a,b) (((a)>(b))?(a):(b))
+#define PyArray_MIN(a,b) (((a)<(b))?(a):(b))
+#define PyArray_CLT(p,q) ((((p).real==(q).real) ? ((p).imag < (q).imag) : \
+ ((p).real < (q).real)))
+#define PyArray_CGT(p,q) ((((p).real==(q).real) ? ((p).imag > (q).imag) : \
+ ((p).real > (q).real)))
+#define PyArray_CLE(p,q) ((((p).real==(q).real) ? ((p).imag <= (q).imag) : \
+ ((p).real <= (q).real)))
+#define PyArray_CGE(p,q) ((((p).real==(q).real) ? ((p).imag >= (q).imag) : \
+ ((p).real >= (q).real)))
+#define PyArray_CEQ(p,q) (((p).real==(q).real) && ((p).imag == (q).imag))
+#define PyArray_CNE(p,q) (((p).real!=(q).real) || ((p).imag != (q).imag))
+ * C API: consists of Macros and functions. The MACROS are defined
+ * here.
+#define PyArray_ISCONTIGUOUS(m) PyArray_CHKFLAGS((m), NPY_ARRAY_C_CONTIGUOUS)
+#define PyArray_ISWRITEABLE(m) PyArray_CHKFLAGS((m), NPY_ARRAY_WRITEABLE)
+#define PyArray_ISALIGNED(m) PyArray_CHKFLAGS((m), NPY_ARRAY_ALIGNED)
+#define PyArray_IS_C_CONTIGUOUS(m) PyArray_CHKFLAGS((m), NPY_ARRAY_C_CONTIGUOUS)
+#define PyArray_IS_F_CONTIGUOUS(m) PyArray_CHKFLAGS((m), NPY_ARRAY_F_CONTIGUOUS)
+/* the variable is used in some places, so always define it */
+#define NPY_BEGIN_THREADS_DEF PyThreadState *_save=NULL;
+#if NPY_ALLOW_THREADS
+#define NPY_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
+#define NPY_END_ALLOW_THREADS Py_END_ALLOW_THREADS
+#define NPY_BEGIN_THREADS do {_save = PyEval_SaveThread();} while (0);
+#define NPY_END_THREADS do { if (_save) \
+ { PyEval_RestoreThread(_save); _save = NULL;} } while (0);
+#define NPY_BEGIN_THREADS_THRESHOLDED(loop_size) do { if ((loop_size) > 500) \
+ { _save = PyEval_SaveThread();} } while (0);
+#define NPY_BEGIN_THREADS_DESCR(dtype) \
+ do {if (!(PyDataType_FLAGCHK((dtype), NPY_NEEDS_PYAPI))) \
+ NPY_BEGIN_THREADS;} while (0);
+#define NPY_END_THREADS_DESCR(dtype) \
+ NPY_END_THREADS; } while (0);
+#define NPY_ALLOW_C_API_DEF PyGILState_STATE __save__;
+#define NPY_ALLOW_C_API do {__save__ = PyGILState_Ensure();} while (0);
+#define NPY_DISABLE_C_API do {PyGILState_Release(__save__);} while (0);
+#define NPY_BEGIN_ALLOW_THREADS
+#define NPY_END_ALLOW_THREADS
+#define NPY_BEGIN_THREADS
+#define NPY_END_THREADS
+#define NPY_BEGIN_THREADS_THRESHOLDED(loop_size)
+#define NPY_BEGIN_THREADS_DESCR(dtype)
+#define NPY_END_THREADS_DESCR(dtype)
+#define NPY_ALLOW_C_API_DEF
+#define NPY_ALLOW_C_API
+#define NPY_DISABLE_C_API
+/**********************************
+ * The nditer object, added in 1.6
+ **********************************/
+/* The actual structure of the iterator is an internal detail */
+typedef struct NpyIter_InternalOnly NpyIter;
+/* Iterator function pointers that may be specialized */
+typedef int (NpyIter_IterNextFunc)(NpyIter *iter);
+typedef void (NpyIter_GetMultiIndexFunc)(NpyIter *iter,
+ npy_intp *outcoords);
+/*** Global flags that may be passed to the iterator constructors ***/
+/* Track an index representing C order */
+#define NPY_ITER_C_INDEX 0x00000001
+/* Track an index representing Fortran order */
+#define NPY_ITER_F_INDEX 0x00000002
+/* Track a multi-index */
+#define NPY_ITER_MULTI_INDEX 0x00000004
+/* User code external to the iterator does the 1-dimensional innermost loop */
+#define NPY_ITER_EXTERNAL_LOOP 0x00000008
+/* Convert all the operands to a common data type */
+#define NPY_ITER_COMMON_DTYPE 0x00000010
+/* Operands may hold references, requiring API access during iteration */
+#define NPY_ITER_REFS_OK 0x00000020
+/* Zero-sized operands should be permitted, iteration checks IterSize for 0 */
+#define NPY_ITER_ZEROSIZE_OK 0x00000040
+/* Permits reductions (size-0 stride with dimension size > 1) */
+#define NPY_ITER_REDUCE_OK 0x00000080
+/* Enables sub-range iteration */
+#define NPY_ITER_RANGED 0x00000100
+/* Enables buffering */
+#define NPY_ITER_BUFFERED 0x00000200
+/* When buffering is enabled, grows the inner loop if possible */
+#define NPY_ITER_GROWINNER 0x00000400
+/* Delay allocation of buffers until first Reset* call */
+#define NPY_ITER_DELAY_BUFALLOC 0x00000800
+/* When NPY_KEEPORDER is specified, disable reversing negative-stride axes */
+#define NPY_ITER_DONT_NEGATE_STRIDES 0x00001000
+ * If output operands overlap with other operands (based on heuristics that
+ * has false positives but no false negatives), make temporary copies to
+ * eliminate overlap.
+#define NPY_ITER_COPY_IF_OVERLAP 0x00002000
+/*** Per-operand flags that may be passed to the iterator constructors ***/
+/* The operand will be read from and written to */
+#define NPY_ITER_READWRITE 0x00010000
+/* The operand will only be read from */
+#define NPY_ITER_READONLY 0x00020000
+/* The operand will only be written to */
+#define NPY_ITER_WRITEONLY 0x00040000
+/* The operand's data must be in native byte order */
+#define NPY_ITER_NBO 0x00080000
+/* The operand's data must be aligned */
+#define NPY_ITER_ALIGNED 0x00100000
+/* The operand's data must be contiguous (within the inner loop) */
+#define NPY_ITER_CONTIG 0x00200000
+/* The operand may be copied to satisfy requirements */
+#define NPY_ITER_COPY 0x00400000
+/* The operand may be copied with WRITEBACKIFCOPY to satisfy requirements */
+#define NPY_ITER_UPDATEIFCOPY 0x00800000
+/* Allocate the operand if it is NULL */
+#define NPY_ITER_ALLOCATE 0x01000000
+/* If an operand is allocated, don't use any subtype */
+#define NPY_ITER_NO_SUBTYPE 0x02000000
+/* This is a virtual array slot, operand is NULL but temporary data is there */
+#define NPY_ITER_VIRTUAL 0x04000000
+/* Require that the dimension match the iterator dimensions exactly */
+#define NPY_ITER_NO_BROADCAST 0x08000000
+/* A mask is being used on this array, affects buffer -> array copy */
+#define NPY_ITER_WRITEMASKED 0x10000000
+/* This array is the mask for all WRITEMASKED operands */
+#define NPY_ITER_ARRAYMASK 0x20000000
+/* Assume iterator order data access for COPY_IF_OVERLAP */
+#define NPY_ITER_OVERLAP_ASSUME_ELEMENTWISE 0x40000000
+#define NPY_ITER_GLOBAL_FLAGS 0x0000ffff
+#define NPY_ITER_PER_OP_FLAGS 0xffff0000
+/*****************************
+ * Basic iterator object
+ *****************************/
+/* FWD declaration */
+typedef struct PyArrayIterObject_tag PyArrayIterObject;
+ * type of the function which translates a set of coordinates to a
+ * pointer to the data
+typedef char* (*npy_iter_get_dataptr_t)(
+ PyArrayIterObject* iter, const npy_intp*);
+struct PyArrayIterObject_tag {
+ int nd_m1; /* number of dimensions - 1 */
+ npy_intp index, size;
+ npy_intp coordinates[NPY_MAXDIMS];/* N-dimensional loop */
+ npy_intp dims_m1[NPY_MAXDIMS]; /* ao->dimensions - 1 */
+ npy_intp strides[NPY_MAXDIMS]; /* ao->strides or fake */
+ npy_intp backstrides[NPY_MAXDIMS];/* how far to jump back */
+ npy_intp factors[NPY_MAXDIMS]; /* shape factors */
+ PyArrayObject *ao;
+ char *dataptr; /* pointer to current item*/
+ npy_bool contiguous;
+ npy_intp bounds[NPY_MAXDIMS][2];
+ npy_intp limits[NPY_MAXDIMS][2];
+ npy_intp limits_sizes[NPY_MAXDIMS];
+ npy_iter_get_dataptr_t translate;
+} ;
+/* Iterator API */
+#define PyArrayIter_Check(op) PyObject_TypeCheck((op), &PyArrayIter_Type)
+#define _PyAIT(it) ((PyArrayIterObject *)(it))
+#define PyArray_ITER_RESET(it) do { \
+ _PyAIT(it)->index = 0; \
+ _PyAIT(it)->dataptr = PyArray_BYTES(_PyAIT(it)->ao); \
+ memset(_PyAIT(it)->coordinates, 0, \
+ (_PyAIT(it)->nd_m1+1)*sizeof(npy_intp)); \
+} while (0)
+#define _PyArray_ITER_NEXT1(it) do { \
+ (it)->dataptr += _PyAIT(it)->strides[0]; \
+ (it)->coordinates[0]++; \
+#define _PyArray_ITER_NEXT2(it) do { \
+ if ((it)->coordinates[1] < (it)->dims_m1[1]) { \
+ (it)->coordinates[1]++; \
+ (it)->dataptr += (it)->strides[1]; \
+ (it)->coordinates[1] = 0; \
+ (it)->dataptr += (it)->strides[0] - \
+ (it)->backstrides[1]; \
+#define PyArray_ITER_NEXT(it) do { \
+ _PyAIT(it)->index++; \
+ if (_PyAIT(it)->nd_m1 == 0) { \
+ _PyArray_ITER_NEXT1(_PyAIT(it)); \
+ else if (_PyAIT(it)->contiguous) \
+ _PyAIT(it)->dataptr += PyArray_DESCR(_PyAIT(it)->ao)->elsize; \
+ else if (_PyAIT(it)->nd_m1 == 1) { \
+ _PyArray_ITER_NEXT2(_PyAIT(it)); \
+ int __npy_i; \
+ for (__npy_i=_PyAIT(it)->nd_m1; __npy_i >= 0; __npy_i--) { \
+ if (_PyAIT(it)->coordinates[__npy_i] < \
+ _PyAIT(it)->dims_m1[__npy_i]) { \
+ _PyAIT(it)->coordinates[__npy_i]++; \
+ _PyAIT(it)->dataptr += \
+ _PyAIT(it)->strides[__npy_i]; \
+ break; \
+ _PyAIT(it)->coordinates[__npy_i] = 0; \
+ _PyAIT(it)->dataptr -= \
+ _PyAIT(it)->backstrides[__npy_i]; \
+#define PyArray_ITER_GOTO(it, destination) do { \
+ for (__npy_i = _PyAIT(it)->nd_m1; __npy_i>=0; __npy_i--) { \
+ if (destination[__npy_i] < 0) { \
+ destination[__npy_i] += \
+ _PyAIT(it)->dims_m1[__npy_i]+1; \
+ _PyAIT(it)->dataptr += destination[__npy_i] * \
+ _PyAIT(it)->coordinates[__npy_i] = \
+ destination[__npy_i]; \
+ _PyAIT(it)->index += destination[__npy_i] * \
+ ( __npy_i==_PyAIT(it)->nd_m1 ? 1 : \
+ _PyAIT(it)->dims_m1[__npy_i+1]+1) ; \
+#define PyArray_ITER_GOTO1D(it, ind) do { \
+ npy_intp __npy_ind = (npy_intp)(ind); \
+ if (__npy_ind < 0) __npy_ind += _PyAIT(it)->size; \
+ _PyAIT(it)->index = __npy_ind; \
+ _PyAIT(it)->dataptr = PyArray_BYTES(_PyAIT(it)->ao) + \
+ __npy_ind * _PyAIT(it)->strides[0]; \
+ __npy_ind * PyArray_DESCR(_PyAIT(it)->ao)->elsize; \
+ for (__npy_i = 0; __npy_i<=_PyAIT(it)->nd_m1; \
+ __npy_i++) { \
+ (__npy_ind / _PyAIT(it)->factors[__npy_i]) \
+ * _PyAIT(it)->strides[__npy_i]; \
+ __npy_ind %= _PyAIT(it)->factors[__npy_i]; \
+#define PyArray_ITER_DATA(it) ((void *)(_PyAIT(it)->dataptr))
+#define PyArray_ITER_NOTDONE(it) (_PyAIT(it)->index < _PyAIT(it)->size)
+ * Any object passed to PyArray_Broadcast must be binary compatible
+ * with this structure.
+ int numiter; /* number of iters */
+ npy_intp size; /* broadcasted size */
+ npy_intp index; /* current index */
+ int nd; /* number of dims */
+ npy_intp dimensions[NPY_MAXDIMS]; /* dimensions */
+ PyArrayIterObject *iters[NPY_MAXARGS]; /* iterators */
+} PyArrayMultiIterObject;
+#define _PyMIT(m) ((PyArrayMultiIterObject *)(m))
+#define PyArray_MultiIter_RESET(multi) do { \
+ int __npy_mi; \
+ _PyMIT(multi)->index = 0; \
+ for (__npy_mi=0; __npy_mi < _PyMIT(multi)->numiter; __npy_mi++) { \
+ PyArray_ITER_RESET(_PyMIT(multi)->iters[__npy_mi]); \
+#define PyArray_MultiIter_NEXT(multi) do { \
+ _PyMIT(multi)->index++; \
+ PyArray_ITER_NEXT(_PyMIT(multi)->iters[__npy_mi]); \
+#define PyArray_MultiIter_GOTO(multi, dest) do { \
+ PyArray_ITER_GOTO(_PyMIT(multi)->iters[__npy_mi], dest); \
+ _PyMIT(multi)->index = _PyMIT(multi)->iters[0]->index; \
+#define PyArray_MultiIter_GOTO1D(multi, ind) do { \
+ PyArray_ITER_GOTO1D(_PyMIT(multi)->iters[__npy_mi], ind); \
+#define PyArray_MultiIter_DATA(multi, i) \
+ ((void *)(_PyMIT(multi)->iters[i]->dataptr))
+#define PyArray_MultiIter_NEXTi(multi, i) \
+ PyArray_ITER_NEXT(_PyMIT(multi)->iters[i])
+#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
+ * where they were originally.
+ * Multi-iterator portion --- needs to be present in this
+ * order to work with PyArray_Broadcast
+ int numiter; /* number of index-array
+ iterators */
+ npy_intp size; /* size of broadcasted
+ result */
+ NpyIter *outer; /* index objects
+ iterator */
+ void *unused[NPY_MAXDIMS - 2];
+ PyArrayObject *array;
+ /* Flat iterator for the indexed array. For compatibility solely. */
+ PyArrayIterObject *ait;
+ * Subspace array. For binary compatibility (was an iterator,
+ * but only the check for NULL should be used).
+ PyArrayObject *subspace;
+ * if subspace iteration, then this is the array of axes in
+ * the underlying array represented by the index objects
+ int iteraxes[NPY_MAXDIMS];
+ npy_intp fancy_strides[NPY_MAXDIMS];
+ /* pointer when all fancy indices are 0 */
+ char *baseoffset;
+ * after binding consec denotes at which axis the fancy axes
+ * are inserted.
+ int consec;
+ char *dataptr;
+ int nd_fancy;
+ npy_intp fancy_dims[NPY_MAXDIMS];
+ /* Whether the iterator (any of the iterators) requires API */
+ int needs_api;
+ * Extra op information.
+ PyArrayObject *extra_op;
+ PyArray_Descr *extra_op_dtype; /* desired dtype */
+ npy_uint32 *extra_op_flags; /* Iterator flags */
+ NpyIter *extra_op_iter;
+ NpyIter_IterNextFunc *extra_op_next;
+ char **extra_op_ptrs;
+ * Information about the iteration state.
+ NpyIter_IterNextFunc *outer_next;
+ char **outer_ptrs;
+ npy_intp *outer_strides;
+ * Information about the subspace iterator.
+ NpyIter *subspace_iter;
+ NpyIter_IterNextFunc *subspace_next;
+ char **subspace_ptrs;
+ npy_intp *subspace_strides;
+ /* Count for the external loop (which ever it is) for API iteration */
+ npy_intp iter_count;
+} PyArrayMapIterObject;
+enum {
+ NPY_NEIGHBORHOOD_ITER_ZERO_PADDING,
+ NPY_NEIGHBORHOOD_ITER_ONE_PADDING,
+ NPY_NEIGHBORHOOD_ITER_CONSTANT_PADDING,
+ NPY_NEIGHBORHOOD_ITER_CIRCULAR_PADDING,
+ NPY_NEIGHBORHOOD_ITER_MIRROR_PADDING
+ * PyArrayIterObject part: keep this in this exact order
+ * New members
+ npy_intp nd;
+ /* Dimensions is the dimension of the array */
+ npy_intp dimensions[NPY_MAXDIMS];
+ * Neighborhood points coordinates are computed relatively to the
+ * point pointed by _internal_iter
+ PyArrayIterObject* _internal_iter;
+ * To keep a reference to the representation of the constant value
+ * for constant padding
+ char* constant;
+ int mode;
+} PyArrayNeighborhoodIterObject;
+ * Neighborhood iterator API
+/* General: those work for any mode */
+PyArrayNeighborhoodIter_Reset(PyArrayNeighborhoodIterObject* iter);
+PyArrayNeighborhoodIter_Next(PyArrayNeighborhoodIterObject* iter);
+#if 0
+PyArrayNeighborhoodIter_Next2D(PyArrayNeighborhoodIterObject* iter);
+ * Include inline implementations - functions defined there are not
+ * considered public API
+#define _NPY_INCLUDE_NEIGHBORHOOD_IMP
+#include "_neighborhood_iterator_imp.h"
+#undef _NPY_INCLUDE_NEIGHBORHOOD_IMP
+/* The default array type */
+#define NPY_DEFAULT_TYPE NPY_DOUBLE
+ * All sorts of useful ways to look into a PyArrayObject. It is recommended
+ * to use PyArrayObject * objects instead of always casting from PyObject *,
+ * for improved type checking.
+ * In many cases here the macro versions of the accessors are deprecated,
+ * but can't be immediately changed to inline functions because the
+ * preexisting macros accept PyObject * and do automatic casts. Inline
+ * functions accepting PyArrayObject * provides for some compile-time
+ * checking of correctness when working with these objects in C.
+#define PyArray_ISONESEGMENT(m) (PyArray_CHKFLAGS(m, NPY_ARRAY_C_CONTIGUOUS) || \
+ PyArray_CHKFLAGS(m, NPY_ARRAY_F_CONTIGUOUS))
+#define PyArray_ISFORTRAN(m) (PyArray_CHKFLAGS(m, NPY_ARRAY_F_CONTIGUOUS) && \
+ (!PyArray_CHKFLAGS(m, NPY_ARRAY_C_CONTIGUOUS)))
+#define PyArray_FORTRAN_IF(m) ((PyArray_CHKFLAGS(m, NPY_ARRAY_F_CONTIGUOUS) ? \
+ NPY_ARRAY_F_CONTIGUOUS : 0))
+#if (defined(NPY_NO_DEPRECATED_API) && (NPY_1_7_API_VERSION <= NPY_NO_DEPRECATED_API))
+ * Changing access macros into functions, to allow for future hiding
+ * of the internal memory layout. This later hiding will allow the 2.x series
+ * to change the internal representation of arrays without affecting
+ * ABI compatibility.
+PyArray_NDIM(const PyArrayObject *arr)
+ return ((PyArrayObject_fields *)arr)->nd;
+static NPY_INLINE void *
+PyArray_DATA(PyArrayObject *arr)
+ return ((PyArrayObject_fields *)arr)->data;
+static NPY_INLINE char *
+PyArray_BYTES(PyArrayObject *arr)
+static NPY_INLINE npy_intp *
+PyArray_DIMS(PyArrayObject *arr)
+ return ((PyArrayObject_fields *)arr)->dimensions;
+PyArray_STRIDES(PyArrayObject *arr)
+ return ((PyArrayObject_fields *)arr)->strides;
+static NPY_INLINE npy_intp
+PyArray_DIM(const PyArrayObject *arr, int idim)
+ return ((PyArrayObject_fields *)arr)->dimensions[idim];
+PyArray_STRIDE(const PyArrayObject *arr, int istride)
+ return ((PyArrayObject_fields *)arr)->strides[istride];
+static NPY_INLINE NPY_RETURNS_BORROWED_REF PyObject *
+PyArray_BASE(PyArrayObject *arr)
+ return ((PyArrayObject_fields *)arr)->base;
+static NPY_INLINE NPY_RETURNS_BORROWED_REF PyArray_Descr *
+PyArray_DESCR(PyArrayObject *arr)
+ return ((PyArrayObject_fields *)arr)->descr;
+PyArray_FLAGS(const PyArrayObject *arr)
+ return ((PyArrayObject_fields *)arr)->flags;
+PyArray_ITEMSIZE(const PyArrayObject *arr)
+ return ((PyArrayObject_fields *)arr)->descr->elsize;
+PyArray_TYPE(const PyArrayObject *arr)
+ return ((PyArrayObject_fields *)arr)->descr->type_num;
+PyArray_CHKFLAGS(const PyArrayObject *arr, int flags)
+ return (PyArray_FLAGS(arr) & flags) == flags;
+static NPY_INLINE PyObject *
+PyArray_GETITEM(const PyArrayObject *arr, const char *itemptr)
+ return ((PyArrayObject_fields *)arr)->descr->f->getitem(
+ (void *)itemptr, (PyArrayObject *)arr);
+ * SETITEM should only be used if it is known that the value is a scalar
+ * and of a type understood by the arrays dtype.
+ * Use `PyArray_Pack` if the value may be of a different dtype.
+PyArray_SETITEM(PyArrayObject *arr, char *itemptr, PyObject *v)
+ return ((PyArrayObject_fields *)arr)->descr->f->setitem(v, itemptr, arr);
+/* These macros are deprecated as of NumPy 1.7. */
+#define PyArray_NDIM(obj) (((PyArrayObject_fields *)(obj))->nd)
+#define PyArray_BYTES(obj) (((PyArrayObject_fields *)(obj))->data)
+#define PyArray_DATA(obj) ((void *)((PyArrayObject_fields *)(obj))->data)
+#define PyArray_DIMS(obj) (((PyArrayObject_fields *)(obj))->dimensions)
+#define PyArray_STRIDES(obj) (((PyArrayObject_fields *)(obj))->strides)
+#define PyArray_DIM(obj,n) (PyArray_DIMS(obj)[n])
+#define PyArray_STRIDE(obj,n) (PyArray_STRIDES(obj)[n])
+#define PyArray_BASE(obj) (((PyArrayObject_fields *)(obj))->base)
+#define PyArray_DESCR(obj) (((PyArrayObject_fields *)(obj))->descr)
+#define PyArray_FLAGS(obj) (((PyArrayObject_fields *)(obj))->flags)
+#define PyArray_CHKFLAGS(m, FLAGS) \
+ ((((PyArrayObject_fields *)(m))->flags & (FLAGS)) == (FLAGS))
+#define PyArray_ITEMSIZE(obj) \
+ (((PyArrayObject_fields *)(obj))->descr->elsize)
+#define PyArray_TYPE(obj) \
+ (((PyArrayObject_fields *)(obj))->descr->type_num)
+#define PyArray_GETITEM(obj,itemptr) \
+ PyArray_DESCR(obj)->f->getitem((char *)(itemptr), \
+ (PyArrayObject *)(obj))
+#define PyArray_SETITEM(obj,itemptr,v) \
+ PyArray_DESCR(obj)->f->setitem((PyObject *)(v), \
+ (char *)(itemptr), \
+static NPY_INLINE PyArray_Descr *
+PyArray_DTYPE(PyArrayObject *arr)
+PyArray_SHAPE(PyArrayObject *arr)
+ * Enables the specified array flags. Does no checking,
+ * assumes you know what you're doing.
+PyArray_ENABLEFLAGS(PyArrayObject *arr, int flags)
+ ((PyArrayObject_fields *)arr)->flags |= flags;
+ * Clears the specified array flags. Does no checking,
+PyArray_CLEARFLAGS(PyArrayObject *arr, int flags)
+ ((PyArrayObject_fields *)arr)->flags &= ~flags;
+#define PyTypeNum_ISBOOL(type) ((type) == NPY_BOOL)
+#define PyTypeNum_ISUNSIGNED(type) (((type) == NPY_UBYTE) || \
+ ((type) == NPY_USHORT) || \
+ ((type) == NPY_UINT) || \
+ ((type) == NPY_ULONG) || \
+ ((type) == NPY_ULONGLONG))
+#define PyTypeNum_ISSIGNED(type) (((type) == NPY_BYTE) || \
+ ((type) == NPY_SHORT) || \
+ ((type) == NPY_INT) || \
+ ((type) == NPY_LONG) || \
+ ((type) == NPY_LONGLONG))
+#define PyTypeNum_ISINTEGER(type) (((type) >= NPY_BYTE) && \
+ ((type) <= NPY_ULONGLONG))
+#define PyTypeNum_ISFLOAT(type) ((((type) >= NPY_FLOAT) && \
+ ((type) <= NPY_LONGDOUBLE)) || \
+ ((type) == NPY_HALF))
+#define PyTypeNum_ISNUMBER(type) (((type) <= NPY_CLONGDOUBLE) || \
+#define PyTypeNum_ISSTRING(type) (((type) == NPY_STRING) || \
+ ((type) == NPY_UNICODE))
+#define PyTypeNum_ISCOMPLEX(type) (((type) >= NPY_CFLOAT) && \
+ ((type) <= NPY_CLONGDOUBLE))
+#define PyTypeNum_ISPYTHON(type) (((type) == NPY_LONG) || \
+ ((type) == NPY_DOUBLE) || \
+ ((type) == NPY_CDOUBLE) || \
+ ((type) == NPY_BOOL) || \
+ ((type) == NPY_OBJECT ))
+#define PyTypeNum_ISFLEXIBLE(type) (((type) >=NPY_STRING) && \
+ ((type) <=NPY_VOID))
+#define PyTypeNum_ISDATETIME(type) (((type) >=NPY_DATETIME) && \
+ ((type) <=NPY_TIMEDELTA))
+#define PyTypeNum_ISUSERDEF(type) (((type) >= NPY_USERDEF) && \
+ ((type) < NPY_USERDEF+ \
+ NPY_NUMUSERTYPES))
+#define PyTypeNum_ISEXTENDED(type) (PyTypeNum_ISFLEXIBLE(type) || \
+ PyTypeNum_ISUSERDEF(type))
+#define PyTypeNum_ISOBJECT(type) ((type) == NPY_OBJECT)
+#define PyDataType_ISBOOL(obj) PyTypeNum_ISBOOL(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISUNSIGNED(obj) PyTypeNum_ISUNSIGNED(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISSIGNED(obj) PyTypeNum_ISSIGNED(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISINTEGER(obj) PyTypeNum_ISINTEGER(((PyArray_Descr*)(obj))->type_num )
+#define PyDataType_ISFLOAT(obj) PyTypeNum_ISFLOAT(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISNUMBER(obj) PyTypeNum_ISNUMBER(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISSTRING(obj) PyTypeNum_ISSTRING(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISCOMPLEX(obj) PyTypeNum_ISCOMPLEX(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISPYTHON(obj) PyTypeNum_ISPYTHON(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISFLEXIBLE(obj) PyTypeNum_ISFLEXIBLE(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISDATETIME(obj) PyTypeNum_ISDATETIME(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISUSERDEF(obj) PyTypeNum_ISUSERDEF(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISEXTENDED(obj) PyTypeNum_ISEXTENDED(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_ISOBJECT(obj) PyTypeNum_ISOBJECT(((PyArray_Descr*)(obj))->type_num)
+#define PyDataType_HASFIELDS(obj) (((PyArray_Descr *)(obj))->names != NULL)
+#define PyDataType_HASSUBARRAY(dtype) ((dtype)->subarray != NULL)
+#define PyDataType_ISUNSIZED(dtype) ((dtype)->elsize == 0 && \
+ !PyDataType_HASFIELDS(dtype))
+#define PyDataType_MAKEUNSIZED(dtype) ((dtype)->elsize = 0)
+#define PyArray_ISBOOL(obj) PyTypeNum_ISBOOL(PyArray_TYPE(obj))
+#define PyArray_ISUNSIGNED(obj) PyTypeNum_ISUNSIGNED(PyArray_TYPE(obj))
+#define PyArray_ISSIGNED(obj) PyTypeNum_ISSIGNED(PyArray_TYPE(obj))
+#define PyArray_ISINTEGER(obj) PyTypeNum_ISINTEGER(PyArray_TYPE(obj))
+#define PyArray_ISFLOAT(obj) PyTypeNum_ISFLOAT(PyArray_TYPE(obj))
+#define PyArray_ISNUMBER(obj) PyTypeNum_ISNUMBER(PyArray_TYPE(obj))
+#define PyArray_ISSTRING(obj) PyTypeNum_ISSTRING(PyArray_TYPE(obj))
+#define PyArray_ISCOMPLEX(obj) PyTypeNum_ISCOMPLEX(PyArray_TYPE(obj))
+#define PyArray_ISPYTHON(obj) PyTypeNum_ISPYTHON(PyArray_TYPE(obj))
+#define PyArray_ISFLEXIBLE(obj) PyTypeNum_ISFLEXIBLE(PyArray_TYPE(obj))
+#define PyArray_ISDATETIME(obj) PyTypeNum_ISDATETIME(PyArray_TYPE(obj))
+#define PyArray_ISUSERDEF(obj) PyTypeNum_ISUSERDEF(PyArray_TYPE(obj))
+#define PyArray_ISEXTENDED(obj) PyTypeNum_ISEXTENDED(PyArray_TYPE(obj))
+#define PyArray_ISOBJECT(obj) PyTypeNum_ISOBJECT(PyArray_TYPE(obj))
+#define PyArray_HASFIELDS(obj) PyDataType_HASFIELDS(PyArray_DESCR(obj))
+ * FIXME: This should check for a flag on the data-type that
+ * states whether or not it is variable length. Because the
+ * ISFLEXIBLE check is hard-coded to the built-in data-types.
+#define PyArray_ISVARIABLE(obj) PyTypeNum_ISFLEXIBLE(PyArray_TYPE(obj))
+#define PyArray_SAFEALIGNEDCOPY(obj) (PyArray_ISALIGNED(obj) && !PyArray_ISVARIABLE(obj))
+#define NPY_LITTLE '<'
+#define NPY_BIG '>'
+#define NPY_NATIVE '='
+#define NPY_SWAP 's'
+#define NPY_IGNORE '|'
+#define NPY_NATBYTE NPY_BIG
+#define NPY_OPPBYTE NPY_LITTLE
+#define NPY_NATBYTE NPY_LITTLE
+#define NPY_OPPBYTE NPY_BIG
+#define PyArray_ISNBO(arg) ((arg) != NPY_OPPBYTE)
+#define PyArray_IsNativeByteOrder PyArray_ISNBO
+#define PyArray_ISNOTSWAPPED(m) PyArray_ISNBO(PyArray_DESCR(m)->byteorder)
+#define PyArray_ISBYTESWAPPED(m) (!PyArray_ISNOTSWAPPED(m))
+#define PyArray_FLAGSWAP(m, flags) (PyArray_CHKFLAGS(m, flags) && \
+ PyArray_ISNOTSWAPPED(m))
+#define PyArray_ISCARRAY(m) PyArray_FLAGSWAP(m, NPY_ARRAY_CARRAY)
+#define PyArray_ISCARRAY_RO(m) PyArray_FLAGSWAP(m, NPY_ARRAY_CARRAY_RO)
+#define PyArray_ISFARRAY(m) PyArray_FLAGSWAP(m, NPY_ARRAY_FARRAY)
+#define PyArray_ISFARRAY_RO(m) PyArray_FLAGSWAP(m, NPY_ARRAY_FARRAY_RO)
+#define PyArray_ISBEHAVED(m) PyArray_FLAGSWAP(m, NPY_ARRAY_BEHAVED)
+#define PyArray_ISBEHAVED_RO(m) PyArray_FLAGSWAP(m, NPY_ARRAY_ALIGNED)
+#define PyDataType_ISNOTSWAPPED(d) PyArray_ISNBO(((PyArray_Descr *)(d))->byteorder)
+#define PyDataType_ISBYTESWAPPED(d) (!PyDataType_ISNOTSWAPPED(d))
+ * A struct used by PyArray_CreateSortedStridePerm, new in 1.7.
+ npy_intp perm, stride;
+} npy_stride_sort_item;
+ * This is the form of the struct that's stored in the
+ * PyCapsule returned by an array's __array_struct__ attribute. See
+ * https://docs.scipy.org/doc/numpy/reference/arrays.interface.html for the full
+ * documentation.
+ int two; /*
+ * contains the integer 2 as a sanity
+ * check
+ int nd; /* number of dimensions */
+ char typekind; /*
+ * kind in array --- character code of
+ * typestr
+ int itemsize; /* size of each element */
+ int flags; /*
+ * how should be data interpreted. Valid
+ * flags are CONTIGUOUS (1), F_CONTIGUOUS (2),
+ * ALIGNED (0x100), NOTSWAPPED (0x200), and
+ * WRITEABLE (0x400). ARR_HAS_DESCR (0x800)
+ * states that arrdescr field is present in
+ * structure
+ npy_intp *shape; /*
+ * A length-nd array of shape
+ * information
+ npy_intp *strides; /* A length-nd array of stride information */
+ void *data; /* A pointer to the first element of the array */
+ PyObject *descr; /*
+ * A list of fields or NULL (ignored if flags
+ * does not have ARR_HAS_DESCR flag set)
+} PyArrayInterface;
+ * This is a function for hooking into the PyDataMem_NEW/FREE/RENEW functions.
+ * See the documentation for PyDataMem_SetEventHook.
+typedef void (PyDataMem_EventHookFunc)(void *inp, void *outp, size_t size,
+ void *user_data);
+ * PyArray_DTypeMeta related definitions.
+ * As of now, this API is preliminary and will be extended as necessary.
+#if defined(NPY_INTERNAL_BUILD) && NPY_INTERNAL_BUILD
+ * The Structures defined in this block are considered private API and
+ * may change without warning!
+ /* TODO: Make this definition public in the API, as soon as its settled */
+ NPY_NO_EXPORT extern PyTypeObject PyArrayDTypeMeta_Type;
+ typedef struct PyArray_DTypeMeta_tag PyArray_DTypeMeta;
+ typedef PyArray_Descr *(discover_descr_from_pyobject_function)(
+ PyArray_DTypeMeta *cls, PyObject *obj);
+ * Before making this public, we should decide whether it should pass
+ * the type, or allow looking at the object. A possible use-case:
+ * `np.array(np.array([0]), dtype=np.ndarray)`
+ * Could consider arrays that are not `dtype=ndarray` "scalars".
+ typedef int (is_known_scalar_type_function)(
+ PyArray_DTypeMeta *cls, PyTypeObject *obj);
+ typedef PyArray_Descr *(default_descr_function)(PyArray_DTypeMeta *cls);
+ typedef PyArray_DTypeMeta *(common_dtype_function)(
+ PyArray_DTypeMeta *dtype1, PyArray_DTypeMeta *dtyep2);
+ typedef PyArray_Descr *(common_instance_function)(
+ PyArray_Descr *dtype1, PyArray_Descr *dtyep2);
+ * While NumPy DTypes would not need to be heap types the plan is to
+ * make DTypes available in Python at which point they will be heap types.
+ * Since we also wish to add fields to the DType class, this looks like
+ * a typical instance definition, but with PyHeapTypeObject instead of
+ * only the PyObject_HEAD.
+ * This must only be exposed very extremely careful consideration, since
+ * it is a fairly complex construct which may be better to allow
+ * refactoring of.
+ struct PyArray_DTypeMeta_tag {
+ PyHeapTypeObject super;
+ * Most DTypes will have a singleton default instance, for the
+ * parametric legacy DTypes (bytes, string, void, datetime) this
+ * 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;
+ * 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;
+ * Point to the original ArrFuncs.
+ * NOTE: We could make a copy to detect changes to `f`.
+ /* 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.
+ PyObject *castingimpls;
+ };
+#endif /* NPY_INTERNAL_BUILD */
+ * Use the keyword NPY_DEPRECATED_INCLUDES to ensure that the header files
+ * npy_*_*_deprecated_api.h are only included from here and nowhere else.
+#ifdef NPY_DEPRECATED_INCLUDES
+#error "Do not use the reserved keyword NPY_DEPRECATED_INCLUDES."
+#define NPY_DEPRECATED_INCLUDES
+#include "npy_1_7_deprecated_api.h"
+ * There is no file npy_1_8_deprecated_api.h since there are no additional
+ * deprecated API features in NumPy 1.8.
+ * Note to maintainers: insert code like the following in future NumPy
+ * versions.
+ * #if !defined(NPY_NO_DEPRECATED_API) || \
+ * (NPY_NO_DEPRECATED_API < NPY_1_9_API_VERSION)
+ * #include "npy_1_9_deprecated_api.h"
+ * #endif
+#undef NPY_DEPRECATED_INCLUDES
+#endif /* NPY_ARRAYTYPES_H */
@@ -0,0 +1,212 @@
+#ifndef NPY_NOPREFIX_H
+#define NPY_NOPREFIX_H
+ * You can directly include noprefix.h as a backward
+ * compatibility measure
+#ifndef NPY_NO_PREFIX
+#define SIGSETJMP NPY_SIGSETJMP
+#define SIGLONGJMP NPY_SIGLONGJMP
+#define SIGJMP_BUF NPY_SIGJMP_BUF
+#define MAX_DIMS NPY_MAXDIMS
+#define longlong npy_longlong
+#define ulonglong npy_ulonglong
+#define Bool npy_bool
+#define longdouble npy_longdouble
+#define byte npy_byte
+#ifndef _BSD_SOURCE
+#define ushort npy_ushort
+#define uint npy_uint
+#define ulong npy_ulong
+#define ubyte npy_ubyte
+#define cfloat npy_cfloat
+#define cdouble npy_cdouble
+#define clongdouble npy_clongdouble
+#define Int8 npy_int8
+#define UInt8 npy_uint8
+#define Int16 npy_int16
+#define UInt16 npy_uint16
+#define Int32 npy_int32
+#define UInt32 npy_uint32
+#define Int64 npy_int64
+#define UInt64 npy_uint64
+#define Int128 npy_int128
+#define UInt128 npy_uint128
+#define Int256 npy_int256
+#define UInt256 npy_uint256
+#define Float16 npy_float16
+#define Complex32 npy_complex32
+#define Float32 npy_float32
+#define Complex64 npy_complex64
+#define Float64 npy_float64
+#define Complex128 npy_complex128
+#define Float80 npy_float80
+#define Complex160 npy_complex160
+#define Float96 npy_float96
+#define Complex192 npy_complex192
+#define Float128 npy_float128
+#define Complex256 npy_complex256
+#define intp npy_intp
+#define uintp npy_uintp
+#define datetime npy_datetime
+#define timedelta npy_timedelta
+#define SIZEOF_LONGLONG NPY_SIZEOF_LONGLONG
+#define SIZEOF_INTP NPY_SIZEOF_INTP
+#define SIZEOF_UINTP NPY_SIZEOF_UINTP
+#define SIZEOF_HALF NPY_SIZEOF_HALF
+#define SIZEOF_LONGDOUBLE NPY_SIZEOF_LONGDOUBLE
+#define SIZEOF_DATETIME NPY_SIZEOF_DATETIME
+#define SIZEOF_TIMEDELTA NPY_SIZEOF_TIMEDELTA
+#define LONGLONG_FMT NPY_LONGLONG_FMT
+#define ULONGLONG_FMT NPY_ULONGLONG_FMT
+#define LONGLONG_SUFFIX NPY_LONGLONG_SUFFIX
+#define ULONGLONG_SUFFIX NPY_ULONGLONG_SUFFIX
+#define MAX_INT8 127
+#define MIN_INT8 -128
+#define MAX_UINT8 255
+#define MAX_INT16 32767
+#define MIN_INT16 -32768
+#define MAX_UINT16 65535
+#define MAX_INT32 2147483647
+#define MIN_INT32 (-MAX_INT32 - 1)
+#define MAX_UINT32 4294967295U
+#define MAX_INT64 LONGLONG_SUFFIX(9223372036854775807)
+#define MIN_INT64 (-MAX_INT64 - LONGLONG_SUFFIX(1))
+#define MAX_UINT64 ULONGLONG_SUFFIX(18446744073709551615)
+#define MAX_INT128 LONGLONG_SUFFIX(85070591730234615865843651857942052864)
+#define MIN_INT128 (-MAX_INT128 - LONGLONG_SUFFIX(1))
+#define MAX_UINT128 ULONGLONG_SUFFIX(170141183460469231731687303715884105728)
+#define MAX_INT256 LONGLONG_SUFFIX(57896044618658097711785492504343953926634992332820282019728792003956564819967)
+#define MIN_INT256 (-MAX_INT256 - LONGLONG_SUFFIX(1))
+#define MAX_UINT256 ULONGLONG_SUFFIX(115792089237316195423570985008687907853269984665640564039457584007913129639935)
+#define MAX_BYTE NPY_MAX_BYTE
+#define MIN_BYTE NPY_MIN_BYTE
+#define MAX_UBYTE NPY_MAX_UBYTE
+#define MAX_SHORT NPY_MAX_SHORT
+#define MIN_SHORT NPY_MIN_SHORT
+#define MAX_USHORT NPY_MAX_USHORT
+#define MAX_INT NPY_MAX_INT
+#define MIN_INT NPY_MIN_INT
+#define MAX_UINT NPY_MAX_UINT
+#define MAX_LONG NPY_MAX_LONG
+#define MIN_LONG NPY_MIN_LONG
+#define MAX_ULONG NPY_MAX_ULONG
+#define MAX_LONGLONG NPY_MAX_LONGLONG
+#define MIN_LONGLONG NPY_MIN_LONGLONG
+#define MAX_ULONGLONG NPY_MAX_ULONGLONG
+#define MIN_DATETIME NPY_MIN_DATETIME
+#define MAX_DATETIME NPY_MAX_DATETIME
+#define MIN_TIMEDELTA NPY_MIN_TIMEDELTA
+#define MAX_TIMEDELTA NPY_MAX_TIMEDELTA
+#define BITSOF_BOOL NPY_BITSOF_BOOL
+#define BITSOF_CHAR NPY_BITSOF_CHAR
+#define BITSOF_SHORT NPY_BITSOF_SHORT
+#define BITSOF_INT NPY_BITSOF_INT
+#define BITSOF_LONG NPY_BITSOF_LONG
+#define BITSOF_LONGLONG NPY_BITSOF_LONGLONG
+#define BITSOF_HALF NPY_BITSOF_HALF
+#define BITSOF_FLOAT NPY_BITSOF_FLOAT
+#define BITSOF_DOUBLE NPY_BITSOF_DOUBLE
+#define BITSOF_LONGDOUBLE NPY_BITSOF_LONGDOUBLE
+#define BITSOF_DATETIME NPY_BITSOF_DATETIME
+#define BITSOF_TIMEDELTA NPY_BITSOF_TIMEDELTA
+#define _pya_malloc PyArray_malloc
+#define _pya_free PyArray_free
+#define _pya_realloc PyArray_realloc
+#define BEGIN_THREADS_DEF NPY_BEGIN_THREADS_DEF
+#define BEGIN_THREADS NPY_BEGIN_THREADS
+#define END_THREADS NPY_END_THREADS
+#define ALLOW_C_API_DEF NPY_ALLOW_C_API_DEF
+#define ALLOW_C_API NPY_ALLOW_C_API
+#define DISABLE_C_API NPY_DISABLE_C_API
+#define PY_FAIL NPY_FAIL
+#define PY_SUCCEED NPY_SUCCEED
+#ifndef TRUE
+#define TRUE NPY_TRUE
+#ifndef FALSE
+#define FALSE NPY_FALSE
+#define LONGDOUBLE_FMT NPY_LONGDOUBLE_FMT
+#define CONTIGUOUS NPY_CONTIGUOUS
+#define C_CONTIGUOUS NPY_C_CONTIGUOUS
+#define FORTRAN NPY_FORTRAN
+#define F_CONTIGUOUS NPY_F_CONTIGUOUS
+#define OWNDATA NPY_OWNDATA
+#define FORCECAST NPY_FORCECAST
+#define ENSURECOPY NPY_ENSURECOPY
+#define ENSUREARRAY NPY_ENSUREARRAY
+#define ELEMENTSTRIDES NPY_ELEMENTSTRIDES
+#define ALIGNED NPY_ALIGNED
+#define NOTSWAPPED NPY_NOTSWAPPED
+#define WRITEABLE NPY_WRITEABLE
+#define UPDATEIFCOPY NPY_UPDATEIFCOPY
+#define WRITEBACKIFCOPY NPY_ARRAY_WRITEBACKIFCOPY
+#define ARR_HAS_DESCR NPY_ARR_HAS_DESCR
+#define BEHAVED NPY_BEHAVED
+#define BEHAVED_NS NPY_BEHAVED_NS
+#define CARRAY NPY_CARRAY
+#define CARRAY_RO NPY_CARRAY_RO
+#define FARRAY NPY_FARRAY
+#define FARRAY_RO NPY_FARRAY_RO
+#define DEFAULT NPY_DEFAULT
+#define IN_ARRAY NPY_IN_ARRAY
+#define OUT_ARRAY NPY_OUT_ARRAY
+#define INOUT_ARRAY NPY_INOUT_ARRAY
+#define IN_FARRAY NPY_IN_FARRAY
+#define OUT_FARRAY NPY_OUT_FARRAY
+#define INOUT_FARRAY NPY_INOUT_FARRAY
+#define UPDATE_ALL NPY_UPDATE_ALL
+#define OWN_DATA NPY_OWNDATA
+#define BEHAVED_FLAGS NPY_BEHAVED
+#define BEHAVED_FLAGS_NS NPY_BEHAVED_NS
+#define CARRAY_FLAGS_RO NPY_CARRAY_RO
+#define CARRAY_FLAGS NPY_CARRAY
+#define FARRAY_FLAGS NPY_FARRAY
+#define FARRAY_FLAGS_RO NPY_FARRAY_RO
+#define DEFAULT_FLAGS NPY_DEFAULT
+#define UPDATE_ALL_FLAGS NPY_UPDATE_ALL_FLAGS
+#ifndef MIN
+#define MIN PyArray_MIN
+#ifndef MAX
+#define MAX PyArray_MAX
+#define MAX_INTP NPY_MAX_INTP
+#define MIN_INTP NPY_MIN_INTP
+#define MAX_UINTP NPY_MAX_UINTP
+#define INTP_FMT NPY_INTP_FMT
+#define REFCOUNT PyArray_REFCOUNT
+#define MAX_ELSIZE NPY_MAX_ELSIZE
@@ -0,0 +1,125 @@
+#ifndef _NPY_1_7_DEPRECATED_API_H
+#define _NPY_1_7_DEPRECATED_API_H
+#ifndef NPY_DEPRECATED_INCLUDES
+#error "Should never include npy_*_*_deprecated_api directly."
+/* Emit a warning if the user did not specifically request the old API */
+#ifndef NPY_NO_DEPRECATED_API
+#if defined(_WIN32)
+#define _WARN___STR2__(x) #x
+#define _WARN___STR1__(x) _WARN___STR2__(x)
+#define _WARN___LOC__ __FILE__ "(" _WARN___STR1__(__LINE__) ") : Warning Msg: "
+#pragma message(_WARN___LOC__"Using deprecated NumPy API, disable it with " \
+ "#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION")
+#warning "Using deprecated NumPy API, disable it with " \
+ "#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION"
+ * This header exists to collect all dangerous/deprecated NumPy API
+ * as of NumPy 1.7.
+ * This is an attempt to remove bad API, the proliferation of macros,
+ * and namespace pollution currently produced by the NumPy headers.
+/* These array flags are deprecated as of NumPy 1.7 */
+#define NPY_CONTIGUOUS NPY_ARRAY_C_CONTIGUOUS
+#define NPY_FORTRAN NPY_ARRAY_F_CONTIGUOUS
+ * The consistent NPY_ARRAY_* names which don't pollute the NPY_*
+ * namespace were added in NumPy 1.7.
+ * These versions of the carray flags are deprecated, but
+ * probably should only be removed after two releases instead of one.
+#define NPY_C_CONTIGUOUS NPY_ARRAY_C_CONTIGUOUS
+#define NPY_F_CONTIGUOUS NPY_ARRAY_F_CONTIGUOUS
+#define NPY_OWNDATA NPY_ARRAY_OWNDATA
+#define NPY_FORCECAST NPY_ARRAY_FORCECAST
+#define NPY_ENSURECOPY NPY_ARRAY_ENSURECOPY
+#define NPY_ENSUREARRAY NPY_ARRAY_ENSUREARRAY
+#define NPY_ELEMENTSTRIDES NPY_ARRAY_ELEMENTSTRIDES
+#define NPY_ALIGNED NPY_ARRAY_ALIGNED
+#define NPY_NOTSWAPPED NPY_ARRAY_NOTSWAPPED
+#define NPY_WRITEABLE NPY_ARRAY_WRITEABLE
+#define NPY_UPDATEIFCOPY NPY_ARRAY_UPDATEIFCOPY
+#define NPY_BEHAVED NPY_ARRAY_BEHAVED
+#define NPY_BEHAVED_NS NPY_ARRAY_BEHAVED_NS
+#define NPY_CARRAY NPY_ARRAY_CARRAY
+#define NPY_CARRAY_RO NPY_ARRAY_CARRAY_RO
+#define NPY_FARRAY NPY_ARRAY_FARRAY
+#define NPY_FARRAY_RO NPY_ARRAY_FARRAY_RO
+#define NPY_DEFAULT NPY_ARRAY_DEFAULT
+#define NPY_IN_ARRAY NPY_ARRAY_IN_ARRAY
+#define NPY_OUT_ARRAY NPY_ARRAY_OUT_ARRAY
+#define NPY_INOUT_ARRAY NPY_ARRAY_INOUT_ARRAY
+#define NPY_IN_FARRAY NPY_ARRAY_IN_FARRAY
+#define NPY_OUT_FARRAY NPY_ARRAY_OUT_FARRAY
+#define NPY_INOUT_FARRAY NPY_ARRAY_INOUT_FARRAY
+#define NPY_UPDATE_ALL NPY_ARRAY_UPDATE_ALL
+/* This way of accessing the default type is deprecated as of NumPy 1.7 */
+#define PyArray_DEFAULT NPY_DEFAULT_TYPE
+/* These DATETIME bits aren't used internally */
+#define PyDataType_GetDatetimeMetaData(descr) \
+ ((descr->metadata == NULL) ? NULL : \
+ ((PyArray_DatetimeMetaData *)(PyCapsule_GetPointer( \
+ PyDict_GetItemString( \
+ descr->metadata, NPY_METADATA_DTSTR), NULL))))
+ * Deprecated as of NumPy 1.7, this kind of shortcut doesn't
+ * belong in the public API.
+#define NPY_AO PyArrayObject
+ * Deprecated as of NumPy 1.7, an all-lowercase macro doesn't
+#define fortran fortran_
+ * Deprecated as of NumPy 1.7, as it is a namespace-polluting
+ * macro.
+#define FORTRAN_IF PyArray_FORTRAN_IF
+/* Deprecated as of NumPy 1.7, datetime64 uses c_metadata instead */
+#define NPY_METADATA_DTSTR "__timeunit__"
+ * Deprecated as of NumPy 1.7.
+ * The reasoning:
+ * - These are for datetime, but there's no datetime "namespace".
+ * - They just turn NPY_STR_<x> into "<x>", which is just
+ * making something simple be indirected.
+#define NPY_STR_Y "Y"
+#define NPY_STR_M "M"
+#define NPY_STR_W "W"
+#define NPY_STR_D "D"
+#define NPY_STR_h "h"
+#define NPY_STR_m "m"
+#define NPY_STR_s "s"
+#define NPY_STR_ms "ms"
+#define NPY_STR_us "us"
+#define NPY_STR_ns "ns"
+#define NPY_STR_ps "ps"
+#define NPY_STR_fs "fs"
+#define NPY_STR_as "as"
+ * The macros in old_defines.h are Deprecated as of NumPy 1.7 and will be
+ * removed in the next major release.
+#include "old_defines.h"
@@ -0,0 +1,585 @@
+ * This is a convenience header file providing compatibility utilities
+ * for supporting Python 2 and Python 3 in the same code base.
+ * If you want to use this for your own projects, it's recommended to make a
+ * copy of it. Although the stuff below is unlikely to change, we don't provide
+ * strong backwards compatibility guarantees at the moment.
+#ifndef _NPY_3KCOMPAT_H_
+#define _NPY_3KCOMPAT_H_
+#include <stdio.h>
+#ifndef NPY_PY3K
+#define NPY_PY3K 1
+#include "numpy/npy_common.h"
+#include "numpy/ndarrayobject.h"
+ * PyInt -> PyLong
+ * This is a renamed copy of the Python non-limited API function _PyLong_AsInt. It is
+ * included here because it is missing from the PyPy API. It completes the PyLong_As*
+ * group of functions and can be useful in replacing PyInt_Check.
+Npy__PyLong_AsInt(PyObject *obj)
+ int overflow;
+ long result = PyLong_AsLongAndOverflow(obj, &overflow);
+ /* INT_MAX and INT_MIN are defined in Python.h */
+ if (overflow || result > INT_MAX || result < INT_MIN) {
+ /* XXX: could be cute and give a different
+ message for overflow == -1 */
+ PyErr_SetString(PyExc_OverflowError,
+ "Python int too large to convert to C int");
+ return (int)result;
+#if defined(NPY_PY3K)
+/* Return True only if the long fits in a C long */
+static NPY_INLINE int PyInt_Check(PyObject *op) {
+ int overflow = 0;
+ if (!PyLong_Check(op)) {
+ PyLong_AsLongAndOverflow(op, &overflow);
+ return (overflow == 0);
+#define PyInt_FromLong PyLong_FromLong
+#define PyInt_AsLong PyLong_AsLong
+#define PyInt_AS_LONG PyLong_AsLong
+#define PyInt_AsSsize_t PyLong_AsSsize_t
+#define PyNumber_Int PyNumber_Long
+/* NOTE:
+ * Since the PyLong type is very different from the fixed-range PyInt,
+ * we don't define PyInt_Type -> PyLong_Type.
+#endif /* NPY_PY3K */
+/* Py3 changes PySlice_GetIndicesEx' first argument's type to PyObject* */
+#ifdef NPY_PY3K
+# define NpySlice_GetIndicesEx PySlice_GetIndicesEx
+# define NpySlice_GetIndicesEx(op, nop, start, end, step, slicelength) \
+ PySlice_GetIndicesEx((PySliceObject *)op, nop, start, end, step, slicelength)
+#if PY_VERSION_HEX < 0x030900a4
+ /* Introduced in https://github.com/python/cpython/commit/d2ec81a8c99796b51fb8c49b77a7fe369863226f */
+ #define Py_SET_TYPE(obj, type) ((Py_TYPE(obj) = (type)), (void)0)
+ /* Introduced in https://github.com/python/cpython/commit/b10dc3e7a11fcdb97e285882eba6da92594f90f9 */
+ #define Py_SET_SIZE(obj, size) ((Py_SIZE(obj) = (size)), (void)0)
+ /* Introduced in https://github.com/python/cpython/commit/c86a11221df7e37da389f9c6ce6e47ea22dc44ff */
+ #define Py_SET_REFCNT(obj, refcnt) ((Py_REFCNT(obj) = (refcnt)), (void)0)
+#define Npy_EnterRecursiveCall(x) Py_EnterRecursiveCall(x)
+/* Py_SETREF was added in 3.5.2, and only if Py_LIMITED_API is absent */
+#if PY_VERSION_HEX < 0x03050200
+ #define Py_SETREF(op, op2) \
+ PyObject *_py_tmp = (PyObject *)(op); \
+ (op) = (op2); \
+ Py_DECREF(_py_tmp); \
+ } while (0)
+/* introduced in https://github.com/python/cpython/commit/a24107b04c1277e3c1105f98aff5bfa3a98b33a0 */
+#if PY_VERSION_HEX < 0x030800A3
+ static NPY_INLINE PyObject *
+ _PyDict_GetItemStringWithError(PyObject *v, const char *key)
+ PyObject *kv, *rv;
+ kv = PyUnicode_FromString(key);
+ if (kv == NULL) {
+ return NULL;
+ rv = PyDict_GetItemWithError(v, kv);
+ Py_DECREF(kv);
+ return rv;
+ * PyString -> PyBytes
+#define PyString_Type PyBytes_Type
+#define PyString_Check PyBytes_Check
+#define PyStringObject PyBytesObject
+#define PyString_FromString PyBytes_FromString
+#define PyString_FromStringAndSize PyBytes_FromStringAndSize
+#define PyString_AS_STRING PyBytes_AS_STRING
+#define PyString_AsStringAndSize PyBytes_AsStringAndSize
+#define PyString_FromFormat PyBytes_FromFormat
+#define PyString_Concat PyBytes_Concat
+#define PyString_ConcatAndDel PyBytes_ConcatAndDel
+#define PyString_AsString PyBytes_AsString
+#define PyString_GET_SIZE PyBytes_GET_SIZE
+#define PyString_Size PyBytes_Size
+#define PyUString_Type PyUnicode_Type
+#define PyUString_Check PyUnicode_Check
+#define PyUStringObject PyUnicodeObject
+#define PyUString_FromString PyUnicode_FromString
+#define PyUString_FromStringAndSize PyUnicode_FromStringAndSize
+#define PyUString_FromFormat PyUnicode_FromFormat
+#define PyUString_Concat PyUnicode_Concat2
+#define PyUString_ConcatAndDel PyUnicode_ConcatAndDel
+#define PyUString_GET_SIZE PyUnicode_GET_SIZE
+#define PyUString_Size PyUnicode_Size
+#define PyUString_InternFromString PyUnicode_InternFromString
+#define PyUString_Format PyUnicode_Format
+#define PyBaseString_Check(obj) (PyUnicode_Check(obj))
+#define PyBytes_Type PyString_Type
+#define PyBytes_Check PyString_Check
+#define PyBytesObject PyStringObject
+#define PyBytes_FromString PyString_FromString
+#define PyBytes_FromStringAndSize PyString_FromStringAndSize
+#define PyBytes_AS_STRING PyString_AS_STRING
+#define PyBytes_AsStringAndSize PyString_AsStringAndSize
+#define PyBytes_FromFormat PyString_FromFormat
+#define PyBytes_Concat PyString_Concat
+#define PyBytes_ConcatAndDel PyString_ConcatAndDel
+#define PyBytes_AsString PyString_AsString
+#define PyBytes_GET_SIZE PyString_GET_SIZE
+#define PyBytes_Size PyString_Size
+#define PyUString_Type PyString_Type
+#define PyUString_Check PyString_Check
+#define PyUStringObject PyStringObject
+#define PyUString_FromString PyString_FromString
+#define PyUString_FromStringAndSize PyString_FromStringAndSize
+#define PyUString_FromFormat PyString_FromFormat
+#define PyUString_Concat PyString_Concat
+#define PyUString_ConcatAndDel PyString_ConcatAndDel
+#define PyUString_GET_SIZE PyString_GET_SIZE
+#define PyUString_Size PyString_Size
+#define PyUString_InternFromString PyString_InternFromString
+#define PyUString_Format PyString_Format
+#define PyBaseString_Check(obj) (PyBytes_Check(obj) || PyUnicode_Check(obj))
+PyUnicode_ConcatAndDel(PyObject **left, PyObject *right)
+ Py_SETREF(*left, PyUnicode_Concat(*left, right));
+ Py_DECREF(right);
+PyUnicode_Concat2(PyObject **left, PyObject *right)
+ * PyFile_* compatibility
+ * Get a FILE* handle to the file represented by the Python object
+static NPY_INLINE FILE*
+npy_PyFile_Dup2(PyObject *file, char *mode, npy_off_t *orig_pos)
+ int fd, fd2, unbuf;
+ PyObject *ret, *os, *io, *io_raw;
+ npy_off_t pos;
+ FILE *handle;
+ /* For Python 2 PyFileObject, use PyFile_AsFile */
+#if !defined(NPY_PY3K)
+ if (PyFile_Check(file)) {
+ return PyFile_AsFile(file);
+ /* Flush first to ensure things end up in the file in the correct order */
+ ret = PyObject_CallMethod(file, "flush", "");
+ if (ret == NULL) {
+ Py_DECREF(ret);
+ fd = PyObject_AsFileDescriptor(file);
+ if (fd == -1) {
+ * The handle needs to be dup'd because we have to call fclose
+ * at the end
+ os = PyImport_ImportModule("os");
+ if (os == NULL) {
+ ret = PyObject_CallMethod(os, "dup", "i", fd);
+ Py_DECREF(os);
+ fd2 = PyNumber_AsSsize_t(ret, NULL);
+ /* Convert to FILE* handle */
+#ifdef _WIN32
+ handle = _fdopen(fd2, mode);
+ handle = fdopen(fd2, mode);
+ if (handle == NULL) {
+ PyErr_SetString(PyExc_IOError,
+ "Getting a FILE* from a Python file object failed");
+ /* Record the original raw file handle position */
+ *orig_pos = npy_ftell(handle);
+ if (*orig_pos == -1) {
+ /* The io module is needed to determine if buffering is used */
+ io = PyImport_ImportModule("io");
+ if (io == NULL) {
+ fclose(handle);
+ /* File object instances of RawIOBase are unbuffered */
+ io_raw = PyObject_GetAttrString(io, "RawIOBase");
+ Py_DECREF(io);
+ if (io_raw == NULL) {
+ unbuf = PyObject_IsInstance(file, io_raw);
+ Py_DECREF(io_raw);
+ if (unbuf == 1) {
+ /* Succeed if the IO is unbuffered */
+ return handle;
+ else {
+ PyErr_SetString(PyExc_IOError, "obtaining file position failed");
+ /* Seek raw handle to the Python-side position */
+ ret = PyObject_CallMethod(file, "tell", "");
+ pos = PyLong_AsLongLong(ret);
+ if (PyErr_Occurred()) {
+ if (npy_fseek(handle, pos, SEEK_SET) == -1) {
+ PyErr_SetString(PyExc_IOError, "seeking file failed");
+ * Close the dup-ed file handle, and seek the Python one to the current position
+npy_PyFile_DupClose2(PyObject *file, FILE* handle, npy_off_t orig_pos)
+ int fd, unbuf;
+ PyObject *ret, *io, *io_raw;
+ npy_off_t position;
+ /* For Python 2 PyFileObject, do nothing */
+ position = npy_ftell(handle);
+ /* Close the FILE* handle */
+ * Restore original file handle position, in order to not confuse
+ * Python-side data structures
+ if (npy_lseek(fd, orig_pos, SEEK_SET) == -1) {
+ if (position == -1) {
+ /* Seek Python-side handle to the FILE* handle position */
+ ret = PyObject_CallMethod(file, "seek", NPY_OFF_T_PYFMT "i", position, 0);
+npy_PyFile_Check(PyObject *file)
+ int fd;
+ /* For Python 2, check if it is a PyFileObject */
+ PyErr_Clear();
+static NPY_INLINE PyObject*
+npy_PyFile_OpenFile(PyObject *filename, const char *mode)
+ PyObject *open;
+ open = PyDict_GetItemString(PyEval_GetBuiltins(), "open");
+ if (open == NULL) {
+ return PyObject_CallFunction(open, "Os", filename, mode);
+npy_PyFile_CloseFile(PyObject *file)
+ PyObject *ret;
+ ret = PyObject_CallMethod(file, "close", NULL);
+/* This is a copy of _PyErr_ChainExceptions
+npy_PyErr_ChainExceptions(PyObject *exc, PyObject *val, PyObject *tb)
+ if (exc == NULL)
+ return;
+ /* only py3 supports this anyway */
+ #ifdef NPY_PY3K
+ PyObject *exc2, *val2, *tb2;
+ PyErr_Fetch(&exc2, &val2, &tb2);
+ PyErr_NormalizeException(&exc, &val, &tb);
+ if (tb != NULL) {
+ PyException_SetTraceback(val, tb);
+ Py_DECREF(tb);
+ Py_DECREF(exc);
+ PyErr_NormalizeException(&exc2, &val2, &tb2);
+ PyException_SetContext(val2, val);
+ PyErr_Restore(exc2, val2, tb2);
+ #endif
+ PyErr_Restore(exc, val, tb);
+/* This is a copy of _PyErr_ChainExceptions, with:
+ * - a minimal implementation for python 2
+ * - __cause__ used instead of __context__
+npy_PyErr_ChainExceptionsCause(PyObject *exc, PyObject *val, PyObject *tb)
+ PyException_SetCause(val2, val);
+ * PyObject_Cmp
+PyObject_Cmp(PyObject *i1, PyObject *i2, int *cmp)
+ int v;
+ v = PyObject_RichCompareBool(i1, i2, Py_LT);
+ if (v == 1) {
+ *cmp = -1;
+ else if (v == -1) {
+ v = PyObject_RichCompareBool(i1, i2, Py_GT);
+ *cmp = 1;
+ v = PyObject_RichCompareBool(i1, i2, Py_EQ);
+ *cmp = 0;
+ * PyCObject functions adapted to PyCapsules.
+ * The main job here is to get rid of the improved error handling
+ * of PyCapsules. It's a shame...
+NpyCapsule_FromVoidPtr(void *ptr, void (*dtor)(PyObject *))
+ PyObject *ret = PyCapsule_New(ptr, NULL, dtor);
+ return ret;
+NpyCapsule_FromVoidPtrAndDesc(void *ptr, void* context, void (*dtor)(PyObject *))
+ PyObject *ret = NpyCapsule_FromVoidPtr(ptr, dtor);
+ if (ret != NULL && PyCapsule_SetContext(ret, context) != 0) {
+ ret = NULL;
+NpyCapsule_AsVoidPtr(PyObject *obj)
+ void *ret = PyCapsule_GetPointer(obj, NULL);
+NpyCapsule_GetDesc(PyObject *obj)
+ return PyCapsule_GetContext(obj);
+NpyCapsule_Check(PyObject *ptr)
+ return PyCapsule_CheckExact(ptr);
+#endif /* _NPY_3KCOMPAT_H_ */
@@ -0,0 +1,1108 @@
+#ifndef _NPY_COMMON_H_
+#define _NPY_COMMON_H_
+/* need Python.h for npy_intp, npy_uintp */
+/* numpconfig.h is auto-generated */
+#include "numpyconfig.h"
+#ifdef HAVE_NPY_CONFIG_H
+#include <npy_config.h>
+ * using static inline modifiers when defining npy_math functions
+ * allows the compiler to make optimizations when possible
+#ifndef NPY_INLINE_MATH
+#define NPY_INLINE_MATH 1
+ * gcc does not unroll even with -O3
+ * use with care, unrolling on modern cpus rarely speeds things up
+#ifdef HAVE_ATTRIBUTE_OPTIMIZE_UNROLL_LOOPS
+#define NPY_GCC_UNROLL_LOOPS \
+ __attribute__((optimize("unroll-loops")))
+#define NPY_GCC_UNROLL_LOOPS
+/* highest gcc optimization level, enabled autovectorizer */
+#ifdef HAVE_ATTRIBUTE_OPTIMIZE_OPT_3
+#define NPY_GCC_OPT_3 __attribute__((optimize("O3")))
+#define NPY_GCC_OPT_3
+/* compile target attributes */
+#if defined HAVE_ATTRIBUTE_TARGET_AVX && defined HAVE_LINK_AVX
+#define NPY_GCC_TARGET_AVX __attribute__((target("avx")))
+#define NPY_GCC_TARGET_AVX
+#if defined HAVE_ATTRIBUTE_TARGET_AVX2_WITH_INTRINSICS
+#define HAVE_ATTRIBUTE_TARGET_FMA
+#define NPY_GCC_TARGET_FMA __attribute__((target("avx2,fma")))
+#if defined HAVE_ATTRIBUTE_TARGET_AVX2 && defined HAVE_LINK_AVX2
+#define NPY_GCC_TARGET_AVX2 __attribute__((target("avx2")))
+#define NPY_GCC_TARGET_AVX2
+#if defined HAVE_ATTRIBUTE_TARGET_AVX512F && defined HAVE_LINK_AVX512F
+#define NPY_GCC_TARGET_AVX512F __attribute__((target("avx512f")))
+#elif defined HAVE_ATTRIBUTE_TARGET_AVX512F_WITH_INTRINSICS
+#define NPY_GCC_TARGET_AVX512F
+#if defined HAVE_ATTRIBUTE_TARGET_AVX512_SKX && defined HAVE_LINK_AVX512_SKX
+#define NPY_GCC_TARGET_AVX512_SKX __attribute__((target("avx512f,avx512dq,avx512vl,avx512bw,avx512cd")))
+#elif defined HAVE_ATTRIBUTE_TARGET_AVX512_SKX_WITH_INTRINSICS
+#define NPY_GCC_TARGET_AVX512_SKX
+ * mark an argument (starting from 1) that must not be NULL and is not checked
+ * DO NOT USE IF FUNCTION CHECKS FOR NULL!! the compiler will remove the check
+#ifdef HAVE_ATTRIBUTE_NONNULL
+#define NPY_GCC_NONNULL(n) __attribute__((nonnull(n)))
+#define NPY_GCC_NONNULL(n)
+#if defined HAVE_XMMINTRIN_H && defined HAVE__MM_LOAD_PS
+#define NPY_HAVE_SSE_INTRINSICS
+#if defined HAVE_EMMINTRIN_H && defined HAVE__MM_LOAD_PD
+#define NPY_HAVE_SSE2_INTRINSICS
+#if defined HAVE_IMMINTRIN_H && defined HAVE_LINK_AVX2
+#define NPY_HAVE_AVX2_INTRINSICS
+#if defined HAVE_IMMINTRIN_H && defined HAVE_LINK_AVX512F
+#define NPY_HAVE_AVX512F_INTRINSICS
+ * give a hint to the compiler which branch is more likely or unlikely
+ * to occur, e.g. rare error cases:
+ * if (NPY_UNLIKELY(failure == 0))
+ * return NULL;
+ * the double !! is to cast the expression (e.g. NULL) to a boolean required by
+ * the intrinsic
+#ifdef HAVE___BUILTIN_EXPECT
+#define NPY_LIKELY(x) __builtin_expect(!!(x), 1)
+#define NPY_UNLIKELY(x) __builtin_expect(!!(x), 0)
+#define NPY_LIKELY(x) (x)
+#define NPY_UNLIKELY(x) (x)
+#ifdef HAVE___BUILTIN_PREFETCH
+/* unlike _mm_prefetch also works on non-x86 */
+#define NPY_PREFETCH(x, rw, loc) __builtin_prefetch((x), (rw), (loc))
+#ifdef HAVE__MM_PREFETCH
+/* _MM_HINT_ET[01] (rw = 1) unsupported, only available in gcc >= 4.9 */
+#define NPY_PREFETCH(x, rw, loc) _mm_prefetch((x), loc == 0 ? _MM_HINT_NTA : \
+ (loc == 1 ? _MM_HINT_T2 : \
+ (loc == 2 ? _MM_HINT_T1 : \
+ (loc == 3 ? _MM_HINT_T0 : -1))))
+#define NPY_PREFETCH(x, rw,loc)
+#if defined(_MSC_VER)
+ #define NPY_INLINE __inline
+#elif defined(__GNUC__)
+ #if defined(__STRICT_ANSI__)
+ #define NPY_INLINE __inline__
+ #else
+ #define NPY_INLINE inline
+ #define NPY_INLINE
+ #define NPY_FINLINE static __forceinline
+ #define NPY_FINLINE static NPY_INLINE __attribute__((always_inline))
+ #define NPY_FINLINE static
+#ifdef HAVE___THREAD
+ #define NPY_TLS __thread
+ #ifdef HAVE___DECLSPEC_THREAD_
+ #define NPY_TLS __declspec(thread)
+ #define NPY_TLS
+#ifdef WITH_CPYCHECKER_RETURNS_BORROWED_REF_ATTRIBUTE
+ #define NPY_RETURNS_BORROWED_REF \
+ __attribute__((cpychecker_returns_borrowed_ref))
+ #define NPY_RETURNS_BORROWED_REF
+#ifdef WITH_CPYCHECKER_STEALS_REFERENCE_TO_ARG_ATTRIBUTE
+ #define NPY_STEALS_REF_TO_ARG(n) \
+ __attribute__((cpychecker_steals_reference_to_arg(n)))
+ #define NPY_STEALS_REF_TO_ARG(n)
+/* 64 bit file position support, also on win-amd64. Ticket #1660 */
+#if defined(_MSC_VER) && defined(_WIN64) && (_MSC_VER > 1400) || \
+ defined(__MINGW32__) || defined(__MINGW64__)
+ #include <io.h>
+/* mingw based on 3.4.5 has lseek but not ftell/fseek */
+#if defined(__MINGW32__) || defined(__MINGW64__)
+extern int __cdecl _fseeki64(FILE *, long long, int);
+extern long long __cdecl _ftelli64(FILE *);
+ #define npy_fseek _fseeki64
+ #define npy_ftell _ftelli64
+ #define npy_lseek _lseeki64
+ #define npy_off_t npy_int64
+ #if NPY_SIZEOF_INT == 8
+ #define NPY_OFF_T_PYFMT "i"
+ #elif NPY_SIZEOF_LONG == 8
+ #define NPY_OFF_T_PYFMT "l"
+ #elif NPY_SIZEOF_LONGLONG == 8
+ #define NPY_OFF_T_PYFMT "L"
+ #error Unsupported size for type off_t
+#ifdef HAVE_FSEEKO
+ #define npy_fseek fseeko
+ #define npy_fseek fseek
+#ifdef HAVE_FTELLO
+ #define npy_ftell ftello
+ #define npy_ftell ftell
+ #include <sys/types.h>
+ #define npy_lseek lseek
+ #define npy_off_t off_t
+ #if NPY_SIZEOF_OFF_T == NPY_SIZEOF_SHORT
+ #define NPY_OFF_T_PYFMT "h"
+ #elif NPY_SIZEOF_OFF_T == NPY_SIZEOF_INT
+ #elif NPY_SIZEOF_OFF_T == NPY_SIZEOF_LONG
+ #elif NPY_SIZEOF_OFF_T == NPY_SIZEOF_LONGLONG
+/* enums for detected endianness */
+ NPY_CPU_UNKNOWN_ENDIAN,
+ NPY_CPU_LITTLE,
+ NPY_CPU_BIG
+ * This is to typedef npy_intp to the appropriate pointer size for this
+ * platform. Py_intptr_t, Py_uintptr_t are defined in pyport.h.
+typedef Py_intptr_t npy_intp;
+typedef Py_uintptr_t npy_uintp;
+ * Define sizes that were not defined in numpyconfig.h.
+#define NPY_SIZEOF_CHAR 1
+#define NPY_SIZEOF_BYTE 1
+#define NPY_SIZEOF_DATETIME 8
+#define NPY_SIZEOF_TIMEDELTA 8
+#define NPY_SIZEOF_INTP NPY_SIZEOF_PY_INTPTR_T
+#define NPY_SIZEOF_UINTP NPY_SIZEOF_PY_INTPTR_T
+#define NPY_SIZEOF_HALF 2
+#define NPY_SIZEOF_CFLOAT NPY_SIZEOF_COMPLEX_FLOAT
+#define NPY_SIZEOF_CDOUBLE NPY_SIZEOF_COMPLEX_DOUBLE
+#define NPY_SIZEOF_CLONGDOUBLE NPY_SIZEOF_COMPLEX_LONGDOUBLE
+#ifdef constchar
+#undef constchar
+#define NPY_SSIZE_T_PYFMT "n"
+#define constchar char
+/* NPY_INTP_FMT Note:
+ * Unlike the other NPY_*_FMT macros, which are used with PyOS_snprintf,
+ * NPY_INTP_FMT is used with PyErr_Format and PyUnicode_FromFormat. Those
+ * functions use different formatting codes that are portably specified
+ * according to the Python documentation. See issue gh-2388.
+#if NPY_SIZEOF_PY_INTPTR_T == NPY_SIZEOF_INT
+ #define NPY_INTP NPY_INT
+ #define NPY_UINTP NPY_UINT
+ #define PyIntpArrType_Type PyIntArrType_Type
+ #define PyUIntpArrType_Type PyUIntArrType_Type
+ #define NPY_MAX_INTP NPY_MAX_INT
+ #define NPY_MIN_INTP NPY_MIN_INT
+ #define NPY_MAX_UINTP NPY_MAX_UINT
+ #define NPY_INTP_FMT "d"
+#elif NPY_SIZEOF_PY_INTPTR_T == NPY_SIZEOF_LONG
+ #define NPY_INTP NPY_LONG
+ #define NPY_UINTP NPY_ULONG
+ #define PyIntpArrType_Type PyLongArrType_Type
+ #define PyUIntpArrType_Type PyULongArrType_Type
+ #define NPY_MAX_INTP NPY_MAX_LONG
+ #define NPY_MIN_INTP NPY_MIN_LONG
+ #define NPY_MAX_UINTP NPY_MAX_ULONG
+ #define NPY_INTP_FMT "ld"
+#elif defined(PY_LONG_LONG) && (NPY_SIZEOF_PY_INTPTR_T == NPY_SIZEOF_LONGLONG)
+ #define NPY_INTP NPY_LONGLONG
+ #define NPY_UINTP NPY_ULONGLONG
+ #define PyIntpArrType_Type PyLongLongArrType_Type
+ #define PyUIntpArrType_Type PyULongLongArrType_Type
+ #define NPY_MAX_INTP NPY_MAX_LONGLONG
+ #define NPY_MIN_INTP NPY_MIN_LONGLONG
+ #define NPY_MAX_UINTP NPY_MAX_ULONGLONG
+ #define NPY_INTP_FMT "lld"
+ * We can only use C99 formats for npy_int_p if it is the same as
+ * intp_t, hence the condition on HAVE_UNITPTR_T
+#if (NPY_USE_C99_FORMATS) == 1 \
+ && (defined HAVE_UINTPTR_T) \
+ && (defined HAVE_INTTYPES_H)
+ #include <inttypes.h>
+ #undef NPY_INTP_FMT
+ #define NPY_INTP_FMT PRIdPTR
+ * Some platforms don't define bool, long long, or long double.
+ * Handle that here.
+#define NPY_BYTE_FMT "hhd"
+#define NPY_UBYTE_FMT "hhu"
+#define NPY_SHORT_FMT "hd"
+#define NPY_USHORT_FMT "hu"
+#define NPY_INT_FMT "d"
+#define NPY_UINT_FMT "u"
+#define NPY_LONG_FMT "ld"
+#define NPY_ULONG_FMT "lu"
+#define NPY_HALF_FMT "g"
+#define NPY_FLOAT_FMT "g"
+#define NPY_DOUBLE_FMT "g"
+#ifdef PY_LONG_LONG
+typedef PY_LONG_LONG npy_longlong;
+typedef unsigned PY_LONG_LONG npy_ulonglong;
+# ifdef _MSC_VER
+# define NPY_LONGLONG_FMT "I64d"
+# define NPY_ULONGLONG_FMT "I64u"
+# else
+# define NPY_LONGLONG_FMT "lld"
+# define NPY_ULONGLONG_FMT "llu"
+# endif
+# define NPY_LONGLONG_SUFFIX(x) (x##i64)
+# define NPY_ULONGLONG_SUFFIX(x) (x##Ui64)
+# define NPY_LONGLONG_SUFFIX(x) (x##LL)
+# define NPY_ULONGLONG_SUFFIX(x) (x##ULL)
+typedef long npy_longlong;
+typedef unsigned long npy_ulonglong;
+# define NPY_LONGLONG_SUFFIX(x) (x##L)
+# define NPY_ULONGLONG_SUFFIX(x) (x##UL)
+typedef unsigned char npy_bool;
+#define NPY_FALSE 0
+#define NPY_TRUE 1
+#if NPY_SIZEOF_LONGDOUBLE == NPY_SIZEOF_DOUBLE
+ typedef double npy_longdouble;
+ #define NPY_LONGDOUBLE_FMT "g"
+ typedef long double npy_longdouble;
+ #define NPY_LONGDOUBLE_FMT "Lg"
+#ifndef Py_USING_UNICODE
+#error Must use Python with unicode enabled.
+typedef signed char npy_byte;
+typedef unsigned char npy_ubyte;
+typedef unsigned short npy_ushort;
+typedef unsigned int npy_uint;
+typedef unsigned long npy_ulong;
+/* These are for completeness */
+typedef char npy_char;
+typedef short npy_short;
+typedef int npy_int;
+typedef long npy_long;
+typedef float npy_float;
+typedef double npy_double;
+typedef Py_hash_t npy_hash_t;
+#define NPY_SIZEOF_HASH_T NPY_SIZEOF_INTP
+ * Disabling C99 complex usage: a lot of C code in numpy/scipy rely on being
+ * able to do .real/.imag. Will have to convert code first.
+#if defined(NPY_USE_C99_COMPLEX) && defined(NPY_HAVE_COMPLEX_DOUBLE)
+typedef complex npy_cdouble;
+typedef struct { double real, imag; } npy_cdouble;
+#if defined(NPY_USE_C99_COMPLEX) && defined(NPY_HAVE_COMPLEX_FLOAT)
+typedef complex float npy_cfloat;
+typedef struct { float real, imag; } npy_cfloat;
+#if defined(NPY_USE_C99_COMPLEX) && defined(NPY_HAVE_COMPLEX_LONG_DOUBLE)
+typedef complex long double npy_clongdouble;
+typedef struct {npy_longdouble real, imag;} npy_clongdouble;
+#if NPY_SIZEOF_COMPLEX_DOUBLE != 2 * NPY_SIZEOF_DOUBLE
+#error npy_cdouble definition is not compatible with C99 complex definition ! \
+ Please contact NumPy maintainers and give detailed information about your \
+ compiler and platform
+#if NPY_SIZEOF_COMPLEX_FLOAT != 2 * NPY_SIZEOF_FLOAT
+#error npy_cfloat definition is not compatible with C99 complex definition ! \
+#if NPY_SIZEOF_COMPLEX_LONGDOUBLE != 2 * NPY_SIZEOF_LONGDOUBLE
+#error npy_clongdouble definition is not compatible with C99 complex definition ! \
+typedef struct { npy_longdouble real, imag; } npy_clongdouble;
+ * numarray-style bit-width typedefs
+#define NPY_MAX_INT8 127
+#define NPY_MIN_INT8 -128
+#define NPY_MAX_UINT8 255
+#define NPY_MAX_INT16 32767
+#define NPY_MIN_INT16 -32768
+#define NPY_MAX_UINT16 65535
+#define NPY_MAX_INT32 2147483647
+#define NPY_MIN_INT32 (-NPY_MAX_INT32 - 1)
+#define NPY_MAX_UINT32 4294967295U
+#define NPY_MAX_INT64 NPY_LONGLONG_SUFFIX(9223372036854775807)
+#define NPY_MIN_INT64 (-NPY_MAX_INT64 - NPY_LONGLONG_SUFFIX(1))
+#define NPY_MAX_UINT64 NPY_ULONGLONG_SUFFIX(18446744073709551615)
+#define NPY_MAX_INT128 NPY_LONGLONG_SUFFIX(85070591730234615865843651857942052864)
+#define NPY_MIN_INT128 (-NPY_MAX_INT128 - NPY_LONGLONG_SUFFIX(1))
+#define NPY_MAX_UINT128 NPY_ULONGLONG_SUFFIX(170141183460469231731687303715884105728)
+#define NPY_MAX_INT256 NPY_LONGLONG_SUFFIX(57896044618658097711785492504343953926634992332820282019728792003956564819967)
+#define NPY_MIN_INT256 (-NPY_MAX_INT256 - NPY_LONGLONG_SUFFIX(1))
+#define NPY_MAX_UINT256 NPY_ULONGLONG_SUFFIX(115792089237316195423570985008687907853269984665640564039457584007913129639935)
+#define NPY_MIN_DATETIME NPY_MIN_INT64
+#define NPY_MAX_DATETIME NPY_MAX_INT64
+#define NPY_MIN_TIMEDELTA NPY_MIN_INT64
+#define NPY_MAX_TIMEDELTA NPY_MAX_INT64
+ /* Need to find the number of bits for each type and
+ make definitions accordingly.
+ C states that sizeof(char) == 1 by definition
+ So, just using the sizeof keyword won't help.
+ It also looks like Python itself uses sizeof(char) quite a
+ bit, which by definition should be 1 all the time.
+ Idea: Make Use of CHAR_BIT which should tell us how many
+ BITS per CHARACTER
+ /* Include platform definitions -- These are in the C89/90 standard */
+#include <limits.h>
+#define NPY_MAX_BYTE SCHAR_MAX
+#define NPY_MIN_BYTE SCHAR_MIN
+#define NPY_MAX_UBYTE UCHAR_MAX
+#define NPY_MAX_SHORT SHRT_MAX
+#define NPY_MIN_SHORT SHRT_MIN
+#define NPY_MAX_USHORT USHRT_MAX
+#define NPY_MAX_INT INT_MAX
+#ifndef INT_MIN
+#define INT_MIN (-INT_MAX - 1)
+#define NPY_MIN_INT INT_MIN
+#define NPY_MAX_UINT UINT_MAX
+#define NPY_MAX_LONG LONG_MAX
+#define NPY_MIN_LONG LONG_MIN
+#define NPY_MAX_ULONG ULONG_MAX
+#define NPY_BITSOF_BOOL (sizeof(npy_bool) * CHAR_BIT)
+#define NPY_BITSOF_CHAR CHAR_BIT
+#define NPY_BITSOF_BYTE (NPY_SIZEOF_BYTE * CHAR_BIT)
+#define NPY_BITSOF_SHORT (NPY_SIZEOF_SHORT * CHAR_BIT)
+#define NPY_BITSOF_INT (NPY_SIZEOF_INT * CHAR_BIT)
+#define NPY_BITSOF_LONG (NPY_SIZEOF_LONG * CHAR_BIT)
+#define NPY_BITSOF_LONGLONG (NPY_SIZEOF_LONGLONG * CHAR_BIT)
+#define NPY_BITSOF_INTP (NPY_SIZEOF_INTP * CHAR_BIT)
+#define NPY_BITSOF_HALF (NPY_SIZEOF_HALF * CHAR_BIT)
+#define NPY_BITSOF_FLOAT (NPY_SIZEOF_FLOAT * CHAR_BIT)
+#define NPY_BITSOF_DOUBLE (NPY_SIZEOF_DOUBLE * CHAR_BIT)
+#define NPY_BITSOF_LONGDOUBLE (NPY_SIZEOF_LONGDOUBLE * CHAR_BIT)
+#define NPY_BITSOF_CFLOAT (NPY_SIZEOF_CFLOAT * CHAR_BIT)
+#define NPY_BITSOF_CDOUBLE (NPY_SIZEOF_CDOUBLE * CHAR_BIT)
+#define NPY_BITSOF_CLONGDOUBLE (NPY_SIZEOF_CLONGDOUBLE * CHAR_BIT)
+#define NPY_BITSOF_DATETIME (NPY_SIZEOF_DATETIME * CHAR_BIT)
+#define NPY_BITSOF_TIMEDELTA (NPY_SIZEOF_TIMEDELTA * CHAR_BIT)
+#if NPY_BITSOF_LONG == 8
+#define NPY_INT8 NPY_LONG
+#define NPY_UINT8 NPY_ULONG
+ typedef long npy_int8;
+ typedef unsigned long npy_uint8;
+#define PyInt8ScalarObject PyLongScalarObject
+#define PyInt8ArrType_Type PyLongArrType_Type
+#define PyUInt8ScalarObject PyULongScalarObject
+#define PyUInt8ArrType_Type PyULongArrType_Type
+#define NPY_INT8_FMT NPY_LONG_FMT
+#define NPY_UINT8_FMT NPY_ULONG_FMT
+#elif NPY_BITSOF_LONG == 16
+#define NPY_INT16 NPY_LONG
+#define NPY_UINT16 NPY_ULONG
+ typedef long npy_int16;
+ typedef unsigned long npy_uint16;
+#define PyInt16ScalarObject PyLongScalarObject
+#define PyInt16ArrType_Type PyLongArrType_Type
+#define PyUInt16ScalarObject PyULongScalarObject
+#define PyUInt16ArrType_Type PyULongArrType_Type
+#define NPY_INT16_FMT NPY_LONG_FMT
+#define NPY_UINT16_FMT NPY_ULONG_FMT
+#elif NPY_BITSOF_LONG == 32
+#define NPY_INT32 NPY_LONG
+#define NPY_UINT32 NPY_ULONG
+ typedef long npy_int32;
+ typedef unsigned long npy_uint32;
+ typedef unsigned long npy_ucs4;
+#define PyInt32ScalarObject PyLongScalarObject
+#define PyInt32ArrType_Type PyLongArrType_Type
+#define PyUInt32ScalarObject PyULongScalarObject
+#define PyUInt32ArrType_Type PyULongArrType_Type
+#define NPY_INT32_FMT NPY_LONG_FMT
+#define NPY_UINT32_FMT NPY_ULONG_FMT
+#elif NPY_BITSOF_LONG == 64
+#define NPY_INT64 NPY_LONG
+#define NPY_UINT64 NPY_ULONG
+ typedef long npy_int64;
+ typedef unsigned long npy_uint64;
+#define PyInt64ScalarObject PyLongScalarObject
+#define PyInt64ArrType_Type PyLongArrType_Type
+#define PyUInt64ScalarObject PyULongScalarObject
+#define PyUInt64ArrType_Type PyULongArrType_Type
+#define NPY_INT64_FMT NPY_LONG_FMT
+#define NPY_UINT64_FMT NPY_ULONG_FMT
+#define MyPyLong_FromInt64 PyLong_FromLong
+#define MyPyLong_AsInt64 PyLong_AsLong
+#elif NPY_BITSOF_LONG == 128
+#define NPY_INT128 NPY_LONG
+#define NPY_UINT128 NPY_ULONG
+ typedef long npy_int128;
+ typedef unsigned long npy_uint128;
+#define PyInt128ScalarObject PyLongScalarObject
+#define PyInt128ArrType_Type PyLongArrType_Type
+#define PyUInt128ScalarObject PyULongScalarObject
+#define PyUInt128ArrType_Type PyULongArrType_Type
+#define NPY_INT128_FMT NPY_LONG_FMT
+#define NPY_UINT128_FMT NPY_ULONG_FMT
+#if NPY_BITSOF_LONGLONG == 8
+# ifndef NPY_INT8
+# define NPY_INT8 NPY_LONGLONG
+# define NPY_UINT8 NPY_ULONGLONG
+ typedef npy_longlong npy_int8;
+ typedef npy_ulonglong npy_uint8;
+# define PyInt8ScalarObject PyLongLongScalarObject
+# define PyInt8ArrType_Type PyLongLongArrType_Type
+# define PyUInt8ScalarObject PyULongLongScalarObject
+# define PyUInt8ArrType_Type PyULongLongArrType_Type
+#define NPY_INT8_FMT NPY_LONGLONG_FMT
+#define NPY_UINT8_FMT NPY_ULONGLONG_FMT
+# define NPY_MAX_LONGLONG NPY_MAX_INT8
+# define NPY_MIN_LONGLONG NPY_MIN_INT8
+# define NPY_MAX_ULONGLONG NPY_MAX_UINT8
+#elif NPY_BITSOF_LONGLONG == 16
+# ifndef NPY_INT16
+# define NPY_INT16 NPY_LONGLONG
+# define NPY_UINT16 NPY_ULONGLONG
+ typedef npy_longlong npy_int16;
+ typedef npy_ulonglong npy_uint16;
+# define PyInt16ScalarObject PyLongLongScalarObject
+# define PyInt16ArrType_Type PyLongLongArrType_Type
+# define PyUInt16ScalarObject PyULongLongScalarObject
+# define PyUInt16ArrType_Type PyULongLongArrType_Type
+#define NPY_INT16_FMT NPY_LONGLONG_FMT
+#define NPY_UINT16_FMT NPY_ULONGLONG_FMT
+# define NPY_MAX_LONGLONG NPY_MAX_INT16
+# define NPY_MIN_LONGLONG NPY_MIN_INT16
+# define NPY_MAX_ULONGLONG NPY_MAX_UINT16
+#elif NPY_BITSOF_LONGLONG == 32
+# ifndef NPY_INT32
+# define NPY_INT32 NPY_LONGLONG
+# define NPY_UINT32 NPY_ULONGLONG
+ typedef npy_longlong npy_int32;
+ typedef npy_ulonglong npy_uint32;
+ typedef npy_ulonglong npy_ucs4;
+# define PyInt32ScalarObject PyLongLongScalarObject
+# define PyInt32ArrType_Type PyLongLongArrType_Type
+# define PyUInt32ScalarObject PyULongLongScalarObject
+# define PyUInt32ArrType_Type PyULongLongArrType_Type
+#define NPY_INT32_FMT NPY_LONGLONG_FMT
+#define NPY_UINT32_FMT NPY_ULONGLONG_FMT
+# define NPY_MAX_LONGLONG NPY_MAX_INT32
+# define NPY_MIN_LONGLONG NPY_MIN_INT32
+# define NPY_MAX_ULONGLONG NPY_MAX_UINT32
+#elif NPY_BITSOF_LONGLONG == 64
+# ifndef NPY_INT64
+# define NPY_INT64 NPY_LONGLONG
+# define NPY_UINT64 NPY_ULONGLONG
+ typedef npy_longlong npy_int64;
+ typedef npy_ulonglong npy_uint64;
+# define PyInt64ScalarObject PyLongLongScalarObject
+# define PyInt64ArrType_Type PyLongLongArrType_Type
+# define PyUInt64ScalarObject PyULongLongScalarObject
+# define PyUInt64ArrType_Type PyULongLongArrType_Type
+#define NPY_INT64_FMT NPY_LONGLONG_FMT
+#define NPY_UINT64_FMT NPY_ULONGLONG_FMT
+# define MyPyLong_FromInt64 PyLong_FromLongLong
+# define MyPyLong_AsInt64 PyLong_AsLongLong
+# define NPY_MAX_LONGLONG NPY_MAX_INT64
+# define NPY_MIN_LONGLONG NPY_MIN_INT64
+# define NPY_MAX_ULONGLONG NPY_MAX_UINT64
+#elif NPY_BITSOF_LONGLONG == 128
+# ifndef NPY_INT128
+# define NPY_INT128 NPY_LONGLONG
+# define NPY_UINT128 NPY_ULONGLONG
+ typedef npy_longlong npy_int128;
+ typedef npy_ulonglong npy_uint128;
+# define PyInt128ScalarObject PyLongLongScalarObject
+# define PyInt128ArrType_Type PyLongLongArrType_Type
+# define PyUInt128ScalarObject PyULongLongScalarObject
+# define PyUInt128ArrType_Type PyULongLongArrType_Type
+#define NPY_INT128_FMT NPY_LONGLONG_FMT
+#define NPY_UINT128_FMT NPY_ULONGLONG_FMT
+# define NPY_MAX_LONGLONG NPY_MAX_INT128
+# define NPY_MIN_LONGLONG NPY_MIN_INT128
+# define NPY_MAX_ULONGLONG NPY_MAX_UINT128
+#elif NPY_BITSOF_LONGLONG == 256
+# define NPY_INT256 NPY_LONGLONG
+# define NPY_UINT256 NPY_ULONGLONG
+ typedef npy_longlong npy_int256;
+ typedef npy_ulonglong npy_uint256;
+# define PyInt256ScalarObject PyLongLongScalarObject
+# define PyInt256ArrType_Type PyLongLongArrType_Type
+# define PyUInt256ScalarObject PyULongLongScalarObject
+# define PyUInt256ArrType_Type PyULongLongArrType_Type
+#define NPY_INT256_FMT NPY_LONGLONG_FMT
+#define NPY_UINT256_FMT NPY_ULONGLONG_FMT
+# define NPY_MAX_LONGLONG NPY_MAX_INT256
+# define NPY_MIN_LONGLONG NPY_MIN_INT256
+# define NPY_MAX_ULONGLONG NPY_MAX_UINT256
+#if NPY_BITSOF_INT == 8
+#ifndef NPY_INT8
+#define NPY_INT8 NPY_INT
+#define NPY_UINT8 NPY_UINT
+ typedef int npy_int8;
+ typedef unsigned int npy_uint8;
+# define PyInt8ScalarObject PyIntScalarObject
+# define PyInt8ArrType_Type PyIntArrType_Type
+# define PyUInt8ScalarObject PyUIntScalarObject
+# define PyUInt8ArrType_Type PyUIntArrType_Type
+#define NPY_INT8_FMT NPY_INT_FMT
+#define NPY_UINT8_FMT NPY_UINT_FMT
+#elif NPY_BITSOF_INT == 16
+#ifndef NPY_INT16
+#define NPY_INT16 NPY_INT
+#define NPY_UINT16 NPY_UINT
+ typedef int npy_int16;
+ typedef unsigned int npy_uint16;
+# define PyInt16ScalarObject PyIntScalarObject
+# define PyInt16ArrType_Type PyIntArrType_Type
+# define PyUInt16ScalarObject PyIntUScalarObject
+# define PyUInt16ArrType_Type PyIntUArrType_Type
+#define NPY_INT16_FMT NPY_INT_FMT
+#define NPY_UINT16_FMT NPY_UINT_FMT
+#elif NPY_BITSOF_INT == 32
+#ifndef NPY_INT32
+#define NPY_INT32 NPY_INT
+#define NPY_UINT32 NPY_UINT
+ typedef int npy_int32;
+ typedef unsigned int npy_uint32;
+ typedef unsigned int npy_ucs4;
+# define PyInt32ScalarObject PyIntScalarObject
+# define PyInt32ArrType_Type PyIntArrType_Type
+# define PyUInt32ScalarObject PyUIntScalarObject
+# define PyUInt32ArrType_Type PyUIntArrType_Type
+#define NPY_INT32_FMT NPY_INT_FMT
+#define NPY_UINT32_FMT NPY_UINT_FMT
+#elif NPY_BITSOF_INT == 64
+#ifndef NPY_INT64
+#define NPY_INT64 NPY_INT
+#define NPY_UINT64 NPY_UINT
+ typedef int npy_int64;
+ typedef unsigned int npy_uint64;
+# define PyInt64ScalarObject PyIntScalarObject
+# define PyInt64ArrType_Type PyIntArrType_Type
+# define PyUInt64ScalarObject PyUIntScalarObject
+# define PyUInt64ArrType_Type PyUIntArrType_Type
+#define NPY_INT64_FMT NPY_INT_FMT
+#define NPY_UINT64_FMT NPY_UINT_FMT
+# define MyPyLong_FromInt64 PyLong_FromLong
+# define MyPyLong_AsInt64 PyLong_AsLong
+#elif NPY_BITSOF_INT == 128
+#ifndef NPY_INT128
+#define NPY_INT128 NPY_INT
+#define NPY_UINT128 NPY_UINT
+ typedef int npy_int128;
+ typedef unsigned int npy_uint128;
+# define PyInt128ScalarObject PyIntScalarObject
+# define PyInt128ArrType_Type PyIntArrType_Type
+# define PyUInt128ScalarObject PyUIntScalarObject
+# define PyUInt128ArrType_Type PyUIntArrType_Type
+#define NPY_INT128_FMT NPY_INT_FMT
+#define NPY_UINT128_FMT NPY_UINT_FMT
+#if NPY_BITSOF_SHORT == 8
+#define NPY_INT8 NPY_SHORT
+#define NPY_UINT8 NPY_USHORT
+ typedef short npy_int8;
+ typedef unsigned short npy_uint8;
+# define PyInt8ScalarObject PyShortScalarObject
+# define PyInt8ArrType_Type PyShortArrType_Type
+# define PyUInt8ScalarObject PyUShortScalarObject
+# define PyUInt8ArrType_Type PyUShortArrType_Type
+#define NPY_INT8_FMT NPY_SHORT_FMT
+#define NPY_UINT8_FMT NPY_USHORT_FMT
+#elif NPY_BITSOF_SHORT == 16
+#define NPY_INT16 NPY_SHORT
+#define NPY_UINT16 NPY_USHORT
+ typedef short npy_int16;
+ typedef unsigned short npy_uint16;
+# define PyInt16ScalarObject PyShortScalarObject
+# define PyInt16ArrType_Type PyShortArrType_Type
+# define PyUInt16ScalarObject PyUShortScalarObject
+# define PyUInt16ArrType_Type PyUShortArrType_Type
+#define NPY_INT16_FMT NPY_SHORT_FMT
+#define NPY_UINT16_FMT NPY_USHORT_FMT
+#elif NPY_BITSOF_SHORT == 32
+#define NPY_INT32 NPY_SHORT
+#define NPY_UINT32 NPY_USHORT
+ typedef short npy_int32;
+ typedef unsigned short npy_uint32;
+ typedef unsigned short npy_ucs4;
+# define PyInt32ScalarObject PyShortScalarObject
+# define PyInt32ArrType_Type PyShortArrType_Type
+# define PyUInt32ScalarObject PyUShortScalarObject
+# define PyUInt32ArrType_Type PyUShortArrType_Type
+#define NPY_INT32_FMT NPY_SHORT_FMT
+#define NPY_UINT32_FMT NPY_USHORT_FMT
+#elif NPY_BITSOF_SHORT == 64
+#define NPY_INT64 NPY_SHORT
+#define NPY_UINT64 NPY_USHORT
+ typedef short npy_int64;
+ typedef unsigned short npy_uint64;
+# define PyInt64ScalarObject PyShortScalarObject
+# define PyInt64ArrType_Type PyShortArrType_Type
+# define PyUInt64ScalarObject PyUShortScalarObject
+# define PyUInt64ArrType_Type PyUShortArrType_Type
+#define NPY_INT64_FMT NPY_SHORT_FMT
+#define NPY_UINT64_FMT NPY_USHORT_FMT
+#elif NPY_BITSOF_SHORT == 128
+#define NPY_INT128 NPY_SHORT
+#define NPY_UINT128 NPY_USHORT
+ typedef short npy_int128;
+ typedef unsigned short npy_uint128;
+# define PyInt128ScalarObject PyShortScalarObject
+# define PyInt128ArrType_Type PyShortArrType_Type
+# define PyUInt128ScalarObject PyUShortScalarObject
+# define PyUInt128ArrType_Type PyUShortArrType_Type
+#define NPY_INT128_FMT NPY_SHORT_FMT
+#define NPY_UINT128_FMT NPY_USHORT_FMT
+#if NPY_BITSOF_CHAR == 8
+#define NPY_INT8 NPY_BYTE
+#define NPY_UINT8 NPY_UBYTE
+ typedef signed char npy_int8;
+ typedef unsigned char npy_uint8;
+# define PyInt8ScalarObject PyByteScalarObject
+# define PyInt8ArrType_Type PyByteArrType_Type
+# define PyUInt8ScalarObject PyUByteScalarObject
+# define PyUInt8ArrType_Type PyUByteArrType_Type
+#define NPY_INT8_FMT NPY_BYTE_FMT
+#define NPY_UINT8_FMT NPY_UBYTE_FMT
+#elif NPY_BITSOF_CHAR == 16
+#define NPY_INT16 NPY_BYTE
+#define NPY_UINT16 NPY_UBYTE
+ typedef signed char npy_int16;
+ typedef unsigned char npy_uint16;
+# define PyInt16ScalarObject PyByteScalarObject
+# define PyInt16ArrType_Type PyByteArrType_Type
+# define PyUInt16ScalarObject PyUByteScalarObject
+# define PyUInt16ArrType_Type PyUByteArrType_Type
+#define NPY_INT16_FMT NPY_BYTE_FMT
+#define NPY_UINT16_FMT NPY_UBYTE_FMT
+#elif NPY_BITSOF_CHAR == 32
+#define NPY_INT32 NPY_BYTE
+#define NPY_UINT32 NPY_UBYTE
+ typedef signed char npy_int32;
+ typedef unsigned char npy_uint32;
+ typedef unsigned char npy_ucs4;
+# define PyInt32ScalarObject PyByteScalarObject
+# define PyInt32ArrType_Type PyByteArrType_Type
+# define PyUInt32ScalarObject PyUByteScalarObject
+# define PyUInt32ArrType_Type PyUByteArrType_Type
+#define NPY_INT32_FMT NPY_BYTE_FMT
+#define NPY_UINT32_FMT NPY_UBYTE_FMT
+#elif NPY_BITSOF_CHAR == 64
+#define NPY_INT64 NPY_BYTE
+#define NPY_UINT64 NPY_UBYTE
+ typedef signed char npy_int64;
+ typedef unsigned char npy_uint64;
+# define PyInt64ScalarObject PyByteScalarObject
+# define PyInt64ArrType_Type PyByteArrType_Type
+# define PyUInt64ScalarObject PyUByteScalarObject
+# define PyUInt64ArrType_Type PyUByteArrType_Type
+#define NPY_INT64_FMT NPY_BYTE_FMT
+#define NPY_UINT64_FMT NPY_UBYTE_FMT
+#elif NPY_BITSOF_CHAR == 128
+#define NPY_INT128 NPY_BYTE
+#define NPY_UINT128 NPY_UBYTE
+ typedef signed char npy_int128;
+ typedef unsigned char npy_uint128;
+# define PyInt128ScalarObject PyByteScalarObject
+# define PyInt128ArrType_Type PyByteArrType_Type
+# define PyUInt128ScalarObject PyUByteScalarObject
+# define PyUInt128ArrType_Type PyUByteArrType_Type
+#define NPY_INT128_FMT NPY_BYTE_FMT
+#define NPY_UINT128_FMT NPY_UBYTE_FMT
+#if NPY_BITSOF_DOUBLE == 32
+#ifndef NPY_FLOAT32
+#define NPY_FLOAT32 NPY_DOUBLE
+#define NPY_COMPLEX64 NPY_CDOUBLE
+ typedef double npy_float32;
+ typedef npy_cdouble npy_complex64;
+# define PyFloat32ScalarObject PyDoubleScalarObject
+# define PyComplex64ScalarObject PyCDoubleScalarObject
+# define PyFloat32ArrType_Type PyDoubleArrType_Type
+# define PyComplex64ArrType_Type PyCDoubleArrType_Type
+#define NPY_FLOAT32_FMT NPY_DOUBLE_FMT
+#define NPY_COMPLEX64_FMT NPY_CDOUBLE_FMT
+#elif NPY_BITSOF_DOUBLE == 64
+#ifndef NPY_FLOAT64
+#define NPY_FLOAT64 NPY_DOUBLE
+#define NPY_COMPLEX128 NPY_CDOUBLE
+ typedef double npy_float64;
+ typedef npy_cdouble npy_complex128;
+# define PyFloat64ScalarObject PyDoubleScalarObject
+# define PyComplex128ScalarObject PyCDoubleScalarObject
+# define PyFloat64ArrType_Type PyDoubleArrType_Type
+# define PyComplex128ArrType_Type PyCDoubleArrType_Type
+#define NPY_FLOAT64_FMT NPY_DOUBLE_FMT
+#define NPY_COMPLEX128_FMT NPY_CDOUBLE_FMT
+#elif NPY_BITSOF_DOUBLE == 80
+#ifndef NPY_FLOAT80
+#define NPY_FLOAT80 NPY_DOUBLE
+#define NPY_COMPLEX160 NPY_CDOUBLE
+ typedef double npy_float80;
+ typedef npy_cdouble npy_complex160;
+# define PyFloat80ScalarObject PyDoubleScalarObject
+# define PyComplex160ScalarObject PyCDoubleScalarObject
+# define PyFloat80ArrType_Type PyDoubleArrType_Type
+# define PyComplex160ArrType_Type PyCDoubleArrType_Type
+#define NPY_FLOAT80_FMT NPY_DOUBLE_FMT
+#define NPY_COMPLEX160_FMT NPY_CDOUBLE_FMT
+#elif NPY_BITSOF_DOUBLE == 96
+#ifndef NPY_FLOAT96
+#define NPY_FLOAT96 NPY_DOUBLE
+#define NPY_COMPLEX192 NPY_CDOUBLE
+ typedef double npy_float96;
+ typedef npy_cdouble npy_complex192;
+# define PyFloat96ScalarObject PyDoubleScalarObject
+# define PyComplex192ScalarObject PyCDoubleScalarObject
+# define PyFloat96ArrType_Type PyDoubleArrType_Type
+# define PyComplex192ArrType_Type PyCDoubleArrType_Type
+#define NPY_FLOAT96_FMT NPY_DOUBLE_FMT
+#define NPY_COMPLEX192_FMT NPY_CDOUBLE_FMT
+#elif NPY_BITSOF_DOUBLE == 128
+#ifndef NPY_FLOAT128
+#define NPY_FLOAT128 NPY_DOUBLE
+#define NPY_COMPLEX256 NPY_CDOUBLE
+ typedef double npy_float128;
+ typedef npy_cdouble npy_complex256;
+# define PyFloat128ScalarObject PyDoubleScalarObject
+# define PyComplex256ScalarObject PyCDoubleScalarObject
+# define PyFloat128ArrType_Type PyDoubleArrType_Type
+# define PyComplex256ArrType_Type PyCDoubleArrType_Type
+#define NPY_FLOAT128_FMT NPY_DOUBLE_FMT
+#define NPY_COMPLEX256_FMT NPY_CDOUBLE_FMT
+#if NPY_BITSOF_FLOAT == 32
+#define NPY_FLOAT32 NPY_FLOAT
+#define NPY_COMPLEX64 NPY_CFLOAT
+ typedef float npy_float32;
+ typedef npy_cfloat npy_complex64;
+# define PyFloat32ScalarObject PyFloatScalarObject
+# define PyComplex64ScalarObject PyCFloatScalarObject
+# define PyFloat32ArrType_Type PyFloatArrType_Type
+# define PyComplex64ArrType_Type PyCFloatArrType_Type
+#define NPY_FLOAT32_FMT NPY_FLOAT_FMT
+#define NPY_COMPLEX64_FMT NPY_CFLOAT_FMT
+#elif NPY_BITSOF_FLOAT == 64
+#define NPY_FLOAT64 NPY_FLOAT
+#define NPY_COMPLEX128 NPY_CFLOAT
+ typedef float npy_float64;
+ typedef npy_cfloat npy_complex128;
+# define PyFloat64ScalarObject PyFloatScalarObject
+# define PyComplex128ScalarObject PyCFloatScalarObject
+# define PyFloat64ArrType_Type PyFloatArrType_Type
+# define PyComplex128ArrType_Type PyCFloatArrType_Type
+#define NPY_FLOAT64_FMT NPY_FLOAT_FMT
+#define NPY_COMPLEX128_FMT NPY_CFLOAT_FMT
+#elif NPY_BITSOF_FLOAT == 80
+#define NPY_FLOAT80 NPY_FLOAT
+#define NPY_COMPLEX160 NPY_CFLOAT
+ typedef float npy_float80;
+ typedef npy_cfloat npy_complex160;
+# define PyFloat80ScalarObject PyFloatScalarObject
+# define PyComplex160ScalarObject PyCFloatScalarObject
+# define PyFloat80ArrType_Type PyFloatArrType_Type
+# define PyComplex160ArrType_Type PyCFloatArrType_Type
+#define NPY_FLOAT80_FMT NPY_FLOAT_FMT
+#define NPY_COMPLEX160_FMT NPY_CFLOAT_FMT
+#elif NPY_BITSOF_FLOAT == 96
+#define NPY_FLOAT96 NPY_FLOAT
+#define NPY_COMPLEX192 NPY_CFLOAT
+ typedef float npy_float96;
+ typedef npy_cfloat npy_complex192;
+# define PyFloat96ScalarObject PyFloatScalarObject
+# define PyComplex192ScalarObject PyCFloatScalarObject
+# define PyFloat96ArrType_Type PyFloatArrType_Type
+# define PyComplex192ArrType_Type PyCFloatArrType_Type
+#define NPY_FLOAT96_FMT NPY_FLOAT_FMT
+#define NPY_COMPLEX192_FMT NPY_CFLOAT_FMT
+#elif NPY_BITSOF_FLOAT == 128
+#define NPY_FLOAT128 NPY_FLOAT
+#define NPY_COMPLEX256 NPY_CFLOAT
+ typedef float npy_float128;
+ typedef npy_cfloat npy_complex256;
+# define PyFloat128ScalarObject PyFloatScalarObject
+# define PyComplex256ScalarObject PyCFloatScalarObject
+# define PyFloat128ArrType_Type PyFloatArrType_Type
+# define PyComplex256ArrType_Type PyCFloatArrType_Type
+#define NPY_FLOAT128_FMT NPY_FLOAT_FMT
+#define NPY_COMPLEX256_FMT NPY_CFLOAT_FMT
+/* half/float16 isn't a floating-point type in C */
+#define NPY_FLOAT16 NPY_HALF
+typedef npy_uint16 npy_half;
+typedef npy_half npy_float16;
+#if NPY_BITSOF_LONGDOUBLE == 32
+#define NPY_FLOAT32 NPY_LONGDOUBLE
+#define NPY_COMPLEX64 NPY_CLONGDOUBLE
+ typedef npy_longdouble npy_float32;
+ typedef npy_clongdouble npy_complex64;
+# define PyFloat32ScalarObject PyLongDoubleScalarObject
+# define PyComplex64ScalarObject PyCLongDoubleScalarObject
+# define PyFloat32ArrType_Type PyLongDoubleArrType_Type
+# define PyComplex64ArrType_Type PyCLongDoubleArrType_Type
+#define NPY_FLOAT32_FMT NPY_LONGDOUBLE_FMT
+#define NPY_COMPLEX64_FMT NPY_CLONGDOUBLE_FMT
+#elif NPY_BITSOF_LONGDOUBLE == 64
+#define NPY_FLOAT64 NPY_LONGDOUBLE
+#define NPY_COMPLEX128 NPY_CLONGDOUBLE
+ typedef npy_longdouble npy_float64;
+ typedef npy_clongdouble npy_complex128;
+# define PyFloat64ScalarObject PyLongDoubleScalarObject
+# define PyComplex128ScalarObject PyCLongDoubleScalarObject
+# define PyFloat64ArrType_Type PyLongDoubleArrType_Type
+# define PyComplex128ArrType_Type PyCLongDoubleArrType_Type
+#define NPY_FLOAT64_FMT NPY_LONGDOUBLE_FMT
+#define NPY_COMPLEX128_FMT NPY_CLONGDOUBLE_FMT
+#elif NPY_BITSOF_LONGDOUBLE == 80
+#define NPY_FLOAT80 NPY_LONGDOUBLE
+#define NPY_COMPLEX160 NPY_CLONGDOUBLE
+ typedef npy_longdouble npy_float80;
+ typedef npy_clongdouble npy_complex160;
+# define PyFloat80ScalarObject PyLongDoubleScalarObject
+# define PyComplex160ScalarObject PyCLongDoubleScalarObject
+# define PyFloat80ArrType_Type PyLongDoubleArrType_Type
+# define PyComplex160ArrType_Type PyCLongDoubleArrType_Type
+#define NPY_FLOAT80_FMT NPY_LONGDOUBLE_FMT
+#define NPY_COMPLEX160_FMT NPY_CLONGDOUBLE_FMT
+#elif NPY_BITSOF_LONGDOUBLE == 96
+#define NPY_FLOAT96 NPY_LONGDOUBLE
+#define NPY_COMPLEX192 NPY_CLONGDOUBLE
+ typedef npy_longdouble npy_float96;
+ typedef npy_clongdouble npy_complex192;
+# define PyFloat96ScalarObject PyLongDoubleScalarObject
+# define PyComplex192ScalarObject PyCLongDoubleScalarObject
+# define PyFloat96ArrType_Type PyLongDoubleArrType_Type
+# define PyComplex192ArrType_Type PyCLongDoubleArrType_Type
+#define NPY_FLOAT96_FMT NPY_LONGDOUBLE_FMT
+#define NPY_COMPLEX192_FMT NPY_CLONGDOUBLE_FMT
+#elif NPY_BITSOF_LONGDOUBLE == 128
+#define NPY_FLOAT128 NPY_LONGDOUBLE
+#define NPY_COMPLEX256 NPY_CLONGDOUBLE
+ typedef npy_longdouble npy_float128;
+ typedef npy_clongdouble npy_complex256;
+# define PyFloat128ScalarObject PyLongDoubleScalarObject
+# define PyComplex256ScalarObject PyCLongDoubleScalarObject
+# define PyFloat128ArrType_Type PyLongDoubleArrType_Type
+# define PyComplex256ArrType_Type PyCLongDoubleArrType_Type
+#define NPY_FLOAT128_FMT NPY_LONGDOUBLE_FMT
+#define NPY_COMPLEX256_FMT NPY_CLONGDOUBLE_FMT
+#elif NPY_BITSOF_LONGDOUBLE == 256
+#define NPY_FLOAT256 NPY_LONGDOUBLE
+#define NPY_COMPLEX512 NPY_CLONGDOUBLE
+ typedef npy_longdouble npy_float256;
+ typedef npy_clongdouble npy_complex512;
+# define PyFloat256ScalarObject PyLongDoubleScalarObject
+# define PyComplex512ScalarObject PyCLongDoubleScalarObject
+# define PyFloat256ArrType_Type PyLongDoubleArrType_Type
+# define PyComplex512ArrType_Type PyCLongDoubleArrType_Type
+#define NPY_FLOAT256_FMT NPY_LONGDOUBLE_FMT
+#define NPY_COMPLEX512_FMT NPY_CLONGDOUBLE_FMT
+/* datetime typedefs */
+typedef npy_int64 npy_timedelta;
+typedef npy_int64 npy_datetime;
+#define NPY_DATETIME_FMT NPY_INT64_FMT
+#define NPY_TIMEDELTA_FMT NPY_INT64_FMT
+/* End of typedefs for numarray style bit-width names */
+ * This set (target) cpu specific macros:
+ * - Possible values:
+ * NPY_CPU_X86
+ * NPY_CPU_AMD64
+ * NPY_CPU_PPC
+ * NPY_CPU_PPC64
+ * NPY_CPU_PPC64LE
+ * NPY_CPU_SPARC
+ * NPY_CPU_S390
+ * NPY_CPU_IA64
+ * NPY_CPU_HPPA
+ * NPY_CPU_ALPHA
+ * NPY_CPU_ARMEL
+ * NPY_CPU_ARMEB
+ * NPY_CPU_SH_LE
+ * NPY_CPU_SH_BE
+ * NPY_CPU_ARCEL
+ * NPY_CPU_ARCEB
+ * NPY_CPU_RISCV64
+ * NPY_CPU_WASM
+#ifndef _NPY_CPUARCH_H_
+#define _NPY_CPUARCH_H_
+#if defined( __i386__ ) || defined(i386) || defined(_M_IX86)
+ * __i386__ is defined by gcc and Intel compiler on Linux,
+ * _M_IX86 by VS compiler,
+ * i386 by Sun compilers on opensolaris at least
+ #define NPY_CPU_X86
+#elif defined(__x86_64__) || defined(__amd64__) || defined(__x86_64) || defined(_M_AMD64)
+ * both __x86_64__ and __amd64__ are defined by gcc
+ * __x86_64 defined by sun compiler on opensolaris at least
+ * _M_AMD64 defined by MS compiler
+ #define NPY_CPU_AMD64
+#elif defined(__powerpc64__) && defined(__LITTLE_ENDIAN__)
+ #define NPY_CPU_PPC64LE
+#elif defined(__powerpc64__) && defined(__BIG_ENDIAN__)
+ #define NPY_CPU_PPC64
+#elif defined(__ppc__) || defined(__powerpc__) || defined(_ARCH_PPC)
+ * __ppc__ is defined by gcc, I remember having seen __powerpc__ once,
+ * but can't find it ATM
+ * _ARCH_PPC is used by at least gcc on AIX
+ * As __powerpc__ and _ARCH_PPC are also defined by PPC64 check
+ * for those specifically first before defaulting to ppc
+ #define NPY_CPU_PPC
+#elif defined(__sparc__) || defined(__sparc)
+ /* __sparc__ is defined by gcc and Forte (e.g. Sun) compilers */
+ #define NPY_CPU_SPARC
+#elif defined(__s390__)
+ #define NPY_CPU_S390
+#elif defined(__ia64)
+ #define NPY_CPU_IA64
+#elif defined(__hppa)
+ #define NPY_CPU_HPPA
+#elif defined(__alpha__)
+ #define NPY_CPU_ALPHA
+#elif defined(__arm__) || defined(__aarch64__)
+ #if defined(__ARMEB__) || defined(__AARCH64EB__)
+ #if defined(__ARM_32BIT_STATE)
+ #define NPY_CPU_ARMEB_AARCH32
+ #elif defined(__ARM_64BIT_STATE)
+ #define NPY_CPU_ARMEB_AARCH64
+ #define NPY_CPU_ARMEB
+ #elif defined(__ARMEL__) || defined(__AARCH64EL__)
+ #define NPY_CPU_ARMEL_AARCH32
+ #define NPY_CPU_ARMEL_AARCH64
+ #define NPY_CPU_ARMEL
+ # error Unknown ARM CPU, please report this to numpy maintainers with \
+ information about your platform (OS, CPU and compiler)
+#elif defined(__sh__) && defined(__LITTLE_ENDIAN__)
+ #define NPY_CPU_SH_LE
+#elif defined(__sh__) && defined(__BIG_ENDIAN__)
+ #define NPY_CPU_SH_BE
+#elif defined(__MIPSEL__)
+ #define NPY_CPU_MIPSEL
+#elif defined(__MIPSEB__)
+ #define NPY_CPU_MIPSEB
+#elif defined(__or1k__)
+ #define NPY_CPU_OR1K
+#elif defined(__mc68000__)
+ #define NPY_CPU_M68K
+#elif defined(__arc__) && defined(__LITTLE_ENDIAN__)
+ #define NPY_CPU_ARCEL
+#elif defined(__arc__) && defined(__BIG_ENDIAN__)
+ #define NPY_CPU_ARCEB
+#elif defined(__riscv) && defined(__riscv_xlen) && __riscv_xlen == 64
+ #define NPY_CPU_RISCV64
+#elif defined(__EMSCRIPTEN__)
+ /* __EMSCRIPTEN__ is defined by emscripten: an LLVM-to-Web compiler */
+ #define NPY_CPU_WASM
+ #error Unknown CPU, please report this to numpy maintainers with \
+#if (defined(NPY_CPU_X86) || defined(NPY_CPU_AMD64))
+#define NPY_CPU_HAVE_UNALIGNED_ACCESS 1
+#define NPY_CPU_HAVE_UNALIGNED_ACCESS 0
@@ -0,0 +1,73 @@
+#ifndef _NPY_ENDIAN_H_
+#define _NPY_ENDIAN_H_
+ * NPY_BYTE_ORDER is set to the same value as BYTE_ORDER set by glibc in
+ * endian.h
+#if defined(NPY_HAVE_ENDIAN_H) || defined(NPY_HAVE_SYS_ENDIAN_H)
+ /* Use endian.h if available */
+ #if defined(NPY_HAVE_ENDIAN_H)
+ #include <endian.h>
+ #elif defined(NPY_HAVE_SYS_ENDIAN_H)
+ #include <sys/endian.h>
+ #if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && defined(LITTLE_ENDIAN)
+ #define NPY_BYTE_ORDER BYTE_ORDER
+ #define NPY_LITTLE_ENDIAN LITTLE_ENDIAN
+ #define NPY_BIG_ENDIAN BIG_ENDIAN
+ #elif defined(_BYTE_ORDER) && defined(_BIG_ENDIAN) && defined(_LITTLE_ENDIAN)
+ #define NPY_BYTE_ORDER _BYTE_ORDER
+ #define NPY_LITTLE_ENDIAN _LITTLE_ENDIAN
+ #define NPY_BIG_ENDIAN _BIG_ENDIAN
+ #elif defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN)
+ #define NPY_BYTE_ORDER __BYTE_ORDER
+ #define NPY_LITTLE_ENDIAN __LITTLE_ENDIAN
+ #define NPY_BIG_ENDIAN __BIG_ENDIAN
+#ifndef NPY_BYTE_ORDER
+ /* Set endianness info using target CPU */
+ #include "npy_cpu.h"
+ #define NPY_LITTLE_ENDIAN 1234
+ #define NPY_BIG_ENDIAN 4321
+ #if defined(NPY_CPU_X86) \
+ || defined(NPY_CPU_AMD64) \
+ || defined(NPY_CPU_IA64) \
+ || defined(NPY_CPU_ALPHA) \
+ || defined(NPY_CPU_ARMEL) \
+ || defined(NPY_CPU_ARMEL_AARCH32) \
+ || defined(NPY_CPU_ARMEL_AARCH64) \
+ || defined(NPY_CPU_SH_LE) \
+ || defined(NPY_CPU_MIPSEL) \
+ || defined(NPY_CPU_PPC64LE) \
+ || defined(NPY_CPU_ARCEL) \
+ || defined(NPY_CPU_RISCV64) \
+ || defined(NPY_CPU_WASM)
+ #define NPY_BYTE_ORDER NPY_LITTLE_ENDIAN
+ #elif defined(NPY_CPU_PPC) \
+ || defined(NPY_CPU_SPARC) \
+ || defined(NPY_CPU_S390) \
+ || defined(NPY_CPU_HPPA) \
+ || defined(NPY_CPU_PPC64) \
+ || defined(NPY_CPU_ARMEB) \
+ || defined(NPY_CPU_ARMEB_AARCH32) \
+ || defined(NPY_CPU_ARMEB_AARCH64) \
+ || defined(NPY_CPU_SH_BE) \
+ || defined(NPY_CPU_MIPSEB) \
+ || defined(NPY_CPU_OR1K) \
+ || defined(NPY_CPU_M68K) \
+ || defined(NPY_CPU_ARCEB)
+ #define NPY_BYTE_ORDER NPY_BIG_ENDIAN
+ #error Unknown CPU: can not set endianness
+ * This API is only provided because it is part of publicly exported
+ * headers. Its use is considered DEPRECATED, and it will be removed
+ * eventually.
+ * (This includes the _PyArray_SigintHandler and _PyArray_GetSigintBuf
+ * functions which are however, public API, and not headers.)
+ * Instead of using these non-threadsafe macros consider periodically
+ * querying `PyErr_CheckSignals()` or `PyOS_InterruptOccurred()` will work.
+ * Both of these require holding the GIL, although cpython could add a
+ * version of `PyOS_InterruptOccurred()` which does not. Such a version
+ * actually exists as private API in Python 3.10, and backported to 3.9 and 3.8,
+ * see also https://bugs.python.org/issue41037 and
+ * https://github.com/python/cpython/pull/20599).
+#ifndef NPY_INTERRUPT_H
+#define NPY_INTERRUPT_H
+#ifndef NPY_NO_SIGNAL
+#include <setjmp.h>
+#include <signal.h>
+#ifndef sigsetjmp
+#define NPY_SIGSETJMP(arg1, arg2) setjmp(arg1)
+#define NPY_SIGLONGJMP(arg1, arg2) longjmp(arg1, arg2)
+#define NPY_SIGJMP_BUF jmp_buf
+#define NPY_SIGSETJMP(arg1, arg2) sigsetjmp(arg1, arg2)
+#define NPY_SIGLONGJMP(arg1, arg2) siglongjmp(arg1, arg2)
+#define NPY_SIGJMP_BUF sigjmp_buf
+# define NPY_SIGINT_ON { \
+ PyOS_sighandler_t _npy_sig_save; \
+ _npy_sig_save = PyOS_setsig(SIGINT, _PyArray_SigintHandler); \
+ if (NPY_SIGSETJMP(*((NPY_SIGJMP_BUF *)_PyArray_GetSigintBuf()), \
+ 1) == 0) { \
+# define NPY_SIGINT_OFF } \
+ PyOS_setsig(SIGINT, _npy_sig_save); \
+#else /* NPY_NO_SIGNAL */
+#define NPY_SIGINT_ON
+#define NPY_SIGINT_OFF
+#endif /* HAVE_SIGSETJMP */
+#endif /* NPY_INTERRUPT_H */
@@ -0,0 +1,597 @@
+#ifndef __NPY_MATH_C99_H_
+#define __NPY_MATH_C99_H_
+#include <numpy/npy_common.h>
+#include <math.h>
+#ifdef __SUNPRO_CC
+#include <sunmath.h>
+/* By adding static inline specifiers to npy_math function definitions when
+ appropriate, compiler is given the opportunity to optimize */
+#if NPY_INLINE_MATH
+#define NPY_INPLACE NPY_INLINE static
+#define NPY_INPLACE
+ * NAN and INFINITY like macros (same behavior as glibc for NAN, same as C99
+ * for INFINITY)
+ * XXX: I should test whether INFINITY and NAN are available on the platform
+NPY_INLINE static float __npy_inff(void)
+ const union { npy_uint32 __i; float __f;} __bint = {0x7f800000UL};
+ return __bint.__f;
+NPY_INLINE static float __npy_nanf(void)
+ const union { npy_uint32 __i; float __f;} __bint = {0x7fc00000UL};
+NPY_INLINE static float __npy_pzerof(void)
+ const union { npy_uint32 __i; float __f;} __bint = {0x00000000UL};
+NPY_INLINE static float __npy_nzerof(void)
+ const union { npy_uint32 __i; float __f;} __bint = {0x80000000UL};
+#define NPY_INFINITYF __npy_inff()
+#define NPY_NANF __npy_nanf()
+#define NPY_PZEROF __npy_pzerof()
+#define NPY_NZEROF __npy_nzerof()
+#define NPY_INFINITY ((npy_double)NPY_INFINITYF)
+#define NPY_NAN ((npy_double)NPY_NANF)
+#define NPY_PZERO ((npy_double)NPY_PZEROF)
+#define NPY_NZERO ((npy_double)NPY_NZEROF)
+#define NPY_INFINITYL ((npy_longdouble)NPY_INFINITYF)
+#define NPY_NANL ((npy_longdouble)NPY_NANF)
+#define NPY_PZEROL ((npy_longdouble)NPY_PZEROF)
+#define NPY_NZEROL ((npy_longdouble)NPY_NZEROF)
+ * Useful constants
+#define NPY_E 2.718281828459045235360287471352662498 /* e */
+#define NPY_LOG2E 1.442695040888963407359924681001892137 /* log_2 e */
+#define NPY_LOG10E 0.434294481903251827651128918916605082 /* log_10 e */
+#define NPY_LOGE2 0.693147180559945309417232121458176568 /* log_e 2 */
+#define NPY_LOGE10 2.302585092994045684017991454684364208 /* log_e 10 */
+#define NPY_PI 3.141592653589793238462643383279502884 /* pi */
+#define NPY_PI_2 1.570796326794896619231321691639751442 /* pi/2 */
+#define NPY_PI_4 0.785398163397448309615660845819875721 /* pi/4 */
+#define NPY_1_PI 0.318309886183790671537767526745028724 /* 1/pi */
+#define NPY_2_PI 0.636619772367581343075535053490057448 /* 2/pi */
+#define NPY_EULER 0.577215664901532860606512090082402431 /* Euler constant */
+#define NPY_SQRT2 1.414213562373095048801688724209698079 /* sqrt(2) */
+#define NPY_SQRT1_2 0.707106781186547524400844362104849039 /* 1/sqrt(2) */
+#define NPY_Ef 2.718281828459045235360287471352662498F /* e */
+#define NPY_LOG2Ef 1.442695040888963407359924681001892137F /* log_2 e */
+#define NPY_LOG10Ef 0.434294481903251827651128918916605082F /* log_10 e */
+#define NPY_LOGE2f 0.693147180559945309417232121458176568F /* log_e 2 */
+#define NPY_LOGE10f 2.302585092994045684017991454684364208F /* log_e 10 */
+#define NPY_PIf 3.141592653589793238462643383279502884F /* pi */
+#define NPY_PI_2f 1.570796326794896619231321691639751442F /* pi/2 */
+#define NPY_PI_4f 0.785398163397448309615660845819875721F /* pi/4 */
+#define NPY_1_PIf 0.318309886183790671537767526745028724F /* 1/pi */
+#define NPY_2_PIf 0.636619772367581343075535053490057448F /* 2/pi */
+#define NPY_EULERf 0.577215664901532860606512090082402431F /* Euler constant */
+#define NPY_SQRT2f 1.414213562373095048801688724209698079F /* sqrt(2) */
+#define NPY_SQRT1_2f 0.707106781186547524400844362104849039F /* 1/sqrt(2) */
+#define NPY_El 2.718281828459045235360287471352662498L /* e */
+#define NPY_LOG2El 1.442695040888963407359924681001892137L /* log_2 e */
+#define NPY_LOG10El 0.434294481903251827651128918916605082L /* log_10 e */
+#define NPY_LOGE2l 0.693147180559945309417232121458176568L /* log_e 2 */
+#define NPY_LOGE10l 2.302585092994045684017991454684364208L /* log_e 10 */
+#define NPY_PIl 3.141592653589793238462643383279502884L /* pi */
+#define NPY_PI_2l 1.570796326794896619231321691639751442L /* pi/2 */
+#define NPY_PI_4l 0.785398163397448309615660845819875721L /* pi/4 */
+#define NPY_1_PIl 0.318309886183790671537767526745028724L /* 1/pi */
+#define NPY_2_PIl 0.636619772367581343075535053490057448L /* 2/pi */
+#define NPY_EULERl 0.577215664901532860606512090082402431L /* Euler constant */
+#define NPY_SQRT2l 1.414213562373095048801688724209698079L /* sqrt(2) */
+#define NPY_SQRT1_2l 0.707106781186547524400844362104849039L /* 1/sqrt(2) */
+ * Integer functions.
+NPY_INPLACE npy_uint npy_gcdu(npy_uint a, npy_uint b);
+NPY_INPLACE npy_uint npy_lcmu(npy_uint a, npy_uint b);
+NPY_INPLACE npy_ulong npy_gcdul(npy_ulong a, npy_ulong b);
+NPY_INPLACE npy_ulong npy_lcmul(npy_ulong a, npy_ulong b);
+NPY_INPLACE npy_ulonglong npy_gcdull(npy_ulonglong a, npy_ulonglong b);
+NPY_INPLACE npy_ulonglong npy_lcmull(npy_ulonglong a, npy_ulonglong b);
+NPY_INPLACE npy_int npy_gcd(npy_int a, npy_int b);
+NPY_INPLACE npy_int npy_lcm(npy_int a, npy_int b);
+NPY_INPLACE npy_long npy_gcdl(npy_long a, npy_long b);
+NPY_INPLACE npy_long npy_lcml(npy_long a, npy_long b);
+NPY_INPLACE npy_longlong npy_gcdll(npy_longlong a, npy_longlong b);
+NPY_INPLACE npy_longlong npy_lcmll(npy_longlong a, npy_longlong b);
+NPY_INPLACE npy_ubyte npy_rshiftuhh(npy_ubyte a, npy_ubyte b);
+NPY_INPLACE npy_ubyte npy_lshiftuhh(npy_ubyte a, npy_ubyte b);
+NPY_INPLACE npy_ushort npy_rshiftuh(npy_ushort a, npy_ushort b);
+NPY_INPLACE npy_ushort npy_lshiftuh(npy_ushort a, npy_ushort b);
+NPY_INPLACE npy_uint npy_rshiftu(npy_uint a, npy_uint b);
+NPY_INPLACE npy_uint npy_lshiftu(npy_uint a, npy_uint b);
+NPY_INPLACE npy_ulong npy_rshiftul(npy_ulong a, npy_ulong b);
+NPY_INPLACE npy_ulong npy_lshiftul(npy_ulong a, npy_ulong b);
+NPY_INPLACE npy_ulonglong npy_rshiftull(npy_ulonglong a, npy_ulonglong b);
+NPY_INPLACE npy_ulonglong npy_lshiftull(npy_ulonglong a, npy_ulonglong b);
+NPY_INPLACE npy_byte npy_rshifthh(npy_byte a, npy_byte b);
+NPY_INPLACE npy_byte npy_lshifthh(npy_byte a, npy_byte b);
+NPY_INPLACE npy_short npy_rshifth(npy_short a, npy_short b);
+NPY_INPLACE npy_short npy_lshifth(npy_short a, npy_short b);
+NPY_INPLACE npy_int npy_rshift(npy_int a, npy_int b);
+NPY_INPLACE npy_int npy_lshift(npy_int a, npy_int b);
+NPY_INPLACE npy_long npy_rshiftl(npy_long a, npy_long b);
+NPY_INPLACE npy_long npy_lshiftl(npy_long a, npy_long b);
+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
+ npy_compute_sin,
+ npy_compute_cos
+} NPY_TRIG_OP;
+ * C99 double math funcs
+NPY_INPLACE double npy_sin(double x);
+NPY_INPLACE double npy_cos(double x);
+NPY_INPLACE double npy_tan(double x);
+NPY_INPLACE double npy_sinh(double x);
+NPY_INPLACE double npy_cosh(double x);
+NPY_INPLACE double npy_tanh(double x);
+NPY_INPLACE double npy_asin(double x);
+NPY_INPLACE double npy_acos(double x);
+NPY_INPLACE double npy_atan(double x);
+NPY_INPLACE double npy_log(double x);
+NPY_INPLACE double npy_log10(double x);
+NPY_INPLACE double npy_exp(double x);
+NPY_INPLACE double npy_sqrt(double x);
+NPY_INPLACE double npy_cbrt(double x);
+NPY_INPLACE double npy_fabs(double x);
+NPY_INPLACE double npy_ceil(double x);
+NPY_INPLACE double npy_fmod(double x, double y);
+NPY_INPLACE double npy_floor(double x);
+NPY_INPLACE double npy_expm1(double x);
+NPY_INPLACE double npy_log1p(double x);
+NPY_INPLACE double npy_hypot(double x, double y);
+NPY_INPLACE double npy_acosh(double x);
+NPY_INPLACE double npy_asinh(double xx);
+NPY_INPLACE double npy_atanh(double x);
+NPY_INPLACE double npy_rint(double x);
+NPY_INPLACE double npy_trunc(double x);
+NPY_INPLACE double npy_exp2(double x);
+NPY_INPLACE double npy_log2(double x);
+NPY_INPLACE double npy_atan2(double x, double y);
+NPY_INPLACE double npy_pow(double x, double y);
+NPY_INPLACE double npy_modf(double x, double* y);
+NPY_INPLACE double npy_frexp(double x, int* y);
+NPY_INPLACE double npy_ldexp(double n, int y);
+NPY_INPLACE double npy_copysign(double x, double y);
+double npy_nextafter(double x, double y);
+double npy_spacing(double x);
+ * IEEE 754 fpu handling. Those are guaranteed to be macros
+/* use builtins to avoid function calls in tight loops
+ * only available if npy_config.h is available (= numpys own build) */
+#if HAVE___BUILTIN_ISNAN
+ #define npy_isnan(x) __builtin_isnan(x)
+ #ifndef NPY_HAVE_DECL_ISNAN
+ #define npy_isnan(x) ((x) != (x))
+ #if defined(_MSC_VER) && (_MSC_VER < 1900)
+ #define npy_isnan(x) _isnan((x))
+ #define npy_isnan(x) isnan(x)
+/* only available if npy_config.h is available (= numpys own build) */
+#if HAVE___BUILTIN_ISFINITE
+ #define npy_isfinite(x) __builtin_isfinite(x)
+ #ifndef NPY_HAVE_DECL_ISFINITE
+ #ifdef _MSC_VER
+ #define npy_isfinite(x) _finite((x))
+ #define npy_isfinite(x) !npy_isnan((x) + (-x))
+ #define npy_isfinite(x) isfinite((x))
+#if HAVE___BUILTIN_ISINF
+ #define npy_isinf(x) __builtin_isinf(x)
+ #ifndef NPY_HAVE_DECL_ISINF
+ #define npy_isinf(x) (!npy_isfinite(x) && !npy_isnan(x))
+ #define npy_isinf(x) (!_finite((x)) && !_isnan((x)))
+ #define npy_isinf(x) isinf((x))
+#ifndef NPY_HAVE_DECL_SIGNBIT
+ int _npy_signbit_f(float x);
+ int _npy_signbit_d(double x);
+ int _npy_signbit_ld(long double x);
+ #define npy_signbit(x) \
+ (sizeof (x) == sizeof (long double) ? _npy_signbit_ld (x) \
+ : sizeof (x) == sizeof (double) ? _npy_signbit_d (x) \
+ : _npy_signbit_f (x))
+ #define npy_signbit(x) signbit((x))
+ * float C99 math functions
+NPY_INPLACE float npy_sinf(float x);
+NPY_INPLACE float npy_cosf(float x);
+NPY_INPLACE float npy_tanf(float x);
+NPY_INPLACE float npy_sinhf(float x);
+NPY_INPLACE float npy_coshf(float x);
+NPY_INPLACE float npy_tanhf(float x);
+NPY_INPLACE float npy_fabsf(float x);
+NPY_INPLACE float npy_floorf(float x);
+NPY_INPLACE float npy_ceilf(float x);
+NPY_INPLACE float npy_rintf(float x);
+NPY_INPLACE float npy_truncf(float x);
+NPY_INPLACE float npy_sqrtf(float x);
+NPY_INPLACE float npy_cbrtf(float x);
+NPY_INPLACE float npy_log10f(float x);
+NPY_INPLACE float npy_logf(float x);
+NPY_INPLACE float npy_expf(float x);
+NPY_INPLACE float npy_expm1f(float x);
+NPY_INPLACE float npy_asinf(float x);
+NPY_INPLACE float npy_acosf(float x);
+NPY_INPLACE float npy_atanf(float x);
+NPY_INPLACE float npy_asinhf(float x);
+NPY_INPLACE float npy_acoshf(float x);
+NPY_INPLACE float npy_atanhf(float x);
+NPY_INPLACE float npy_log1pf(float x);
+NPY_INPLACE float npy_exp2f(float x);
+NPY_INPLACE float npy_log2f(float x);
+NPY_INPLACE float npy_atan2f(float x, float y);
+NPY_INPLACE float npy_hypotf(float x, float y);
+NPY_INPLACE float npy_powf(float x, float y);
+NPY_INPLACE float npy_fmodf(float x, float y);
+NPY_INPLACE float npy_modff(float x, float* y);
+NPY_INPLACE float npy_frexpf(float x, int* y);
+NPY_INPLACE float npy_ldexpf(float x, int y);
+NPY_INPLACE float npy_copysignf(float x, float y);
+float npy_nextafterf(float x, float y);
+float npy_spacingf(float x);
+ * long double C99 math functions
+NPY_INPLACE npy_longdouble npy_sinl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_cosl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_tanl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_sinhl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_coshl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_tanhl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_fabsl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_floorl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_ceill(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_rintl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_truncl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_sqrtl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_cbrtl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_log10l(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_logl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_expl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_expm1l(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_asinl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_acosl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_atanl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_asinhl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_acoshl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_atanhl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_log1pl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_exp2l(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_log2l(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_atan2l(npy_longdouble x, npy_longdouble y);
+NPY_INPLACE npy_longdouble npy_hypotl(npy_longdouble x, npy_longdouble y);
+NPY_INPLACE npy_longdouble npy_powl(npy_longdouble x, npy_longdouble y);
+NPY_INPLACE npy_longdouble npy_fmodl(npy_longdouble x, npy_longdouble y);
+NPY_INPLACE npy_longdouble npy_modfl(npy_longdouble x, npy_longdouble* y);
+NPY_INPLACE npy_longdouble npy_frexpl(npy_longdouble x, int* y);
+NPY_INPLACE npy_longdouble npy_ldexpl(npy_longdouble x, int y);
+NPY_INPLACE npy_longdouble npy_copysignl(npy_longdouble x, npy_longdouble y);
+npy_longdouble npy_nextafterl(npy_longdouble x, npy_longdouble y);
+npy_longdouble npy_spacingl(npy_longdouble x);
+ * Non standard functions
+NPY_INPLACE double npy_deg2rad(double x);
+NPY_INPLACE double npy_rad2deg(double x);
+NPY_INPLACE double npy_logaddexp(double x, double y);
+NPY_INPLACE double npy_logaddexp2(double x, double y);
+NPY_INPLACE double npy_divmod(double x, double y, double *modulus);
+NPY_INPLACE double npy_heaviside(double x, double h0);
+NPY_INPLACE float npy_deg2radf(float x);
+NPY_INPLACE float npy_rad2degf(float x);
+NPY_INPLACE float npy_logaddexpf(float x, float y);
+NPY_INPLACE float npy_logaddexp2f(float x, float y);
+NPY_INPLACE float npy_divmodf(float x, float y, float *modulus);
+NPY_INPLACE float npy_heavisidef(float x, float h0);
+NPY_INPLACE npy_longdouble npy_deg2radl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_rad2degl(npy_longdouble x);
+NPY_INPLACE npy_longdouble npy_logaddexpl(npy_longdouble x, npy_longdouble y);
+NPY_INPLACE npy_longdouble npy_logaddexp2l(npy_longdouble x, npy_longdouble y);
+NPY_INPLACE npy_longdouble npy_divmodl(npy_longdouble x, npy_longdouble y,
+ npy_longdouble *modulus);
+NPY_INPLACE npy_longdouble npy_heavisidel(npy_longdouble x, npy_longdouble h0);
+#define npy_degrees npy_rad2deg
+#define npy_degreesf npy_rad2degf
+#define npy_degreesl npy_rad2degl
+#define npy_radians npy_deg2rad
+#define npy_radiansf npy_deg2radf
+#define npy_radiansl npy_deg2radl
+ * Complex declarations
+ * C99 specifies that complex numbers have the same representation as
+ * an array of two elements, where the first element is the real part
+ * and the second element is the imaginary part.
+#define __NPY_CPACK_IMP(x, y, type, ctype) \
+ union { \
+ ctype z; \
+ type a[2]; \
+ } z1;; \
+ \
+ z1.a[0] = (x); \
+ z1.a[1] = (y); \
+ return z1.z;
+static NPY_INLINE npy_cdouble npy_cpack(double x, double y)
+ __NPY_CPACK_IMP(x, y, double, npy_cdouble);
+static NPY_INLINE npy_cfloat npy_cpackf(float x, float y)
+ __NPY_CPACK_IMP(x, y, float, npy_cfloat);
+static NPY_INLINE npy_clongdouble npy_cpackl(npy_longdouble x, npy_longdouble y)
+ __NPY_CPACK_IMP(x, y, npy_longdouble, npy_clongdouble);
+#undef __NPY_CPACK_IMP
+ * Same remark as above, but in the other direction: extract first/second
+ * member of complex number, assuming a C99-compatible representation
+ * Those are defineds as static inline, and such as a reasonable compiler would
+ * most likely compile this to one or two instructions (on CISC at least)
+#define __NPY_CEXTRACT_IMP(z, index, type, ctype) \
+ } __z_repr; \
+ __z_repr.z = z; \
+ return __z_repr.a[index];
+static NPY_INLINE double npy_creal(npy_cdouble z)
+ __NPY_CEXTRACT_IMP(z, 0, double, npy_cdouble);
+static NPY_INLINE double npy_cimag(npy_cdouble z)
+ __NPY_CEXTRACT_IMP(z, 1, double, npy_cdouble);
+static NPY_INLINE float npy_crealf(npy_cfloat z)
+ __NPY_CEXTRACT_IMP(z, 0, float, npy_cfloat);
+static NPY_INLINE float npy_cimagf(npy_cfloat z)
+ __NPY_CEXTRACT_IMP(z, 1, float, npy_cfloat);
+static NPY_INLINE npy_longdouble npy_creall(npy_clongdouble z)
+ __NPY_CEXTRACT_IMP(z, 0, npy_longdouble, npy_clongdouble);
+static NPY_INLINE npy_longdouble npy_cimagl(npy_clongdouble z)
+ __NPY_CEXTRACT_IMP(z, 1, npy_longdouble, npy_clongdouble);
+#undef __NPY_CEXTRACT_IMP
+ * Double precision complex functions
+double npy_cabs(npy_cdouble z);
+double npy_carg(npy_cdouble z);
+npy_cdouble npy_cexp(npy_cdouble z);
+npy_cdouble npy_clog(npy_cdouble z);
+npy_cdouble npy_cpow(npy_cdouble x, npy_cdouble y);
+npy_cdouble npy_csqrt(npy_cdouble z);
+npy_cdouble npy_ccos(npy_cdouble z);
+npy_cdouble npy_csin(npy_cdouble z);
+npy_cdouble npy_ctan(npy_cdouble z);
+npy_cdouble npy_ccosh(npy_cdouble z);
+npy_cdouble npy_csinh(npy_cdouble z);
+npy_cdouble npy_ctanh(npy_cdouble z);
+npy_cdouble npy_cacos(npy_cdouble z);
+npy_cdouble npy_casin(npy_cdouble z);
+npy_cdouble npy_catan(npy_cdouble z);
+npy_cdouble npy_cacosh(npy_cdouble z);
+npy_cdouble npy_casinh(npy_cdouble z);
+npy_cdouble npy_catanh(npy_cdouble z);
+ * Single precision complex functions
+float npy_cabsf(npy_cfloat z);
+float npy_cargf(npy_cfloat z);
+npy_cfloat npy_cexpf(npy_cfloat z);
+npy_cfloat npy_clogf(npy_cfloat z);
+npy_cfloat npy_cpowf(npy_cfloat x, npy_cfloat y);
+npy_cfloat npy_csqrtf(npy_cfloat z);
+npy_cfloat npy_ccosf(npy_cfloat z);
+npy_cfloat npy_csinf(npy_cfloat z);
+npy_cfloat npy_ctanf(npy_cfloat z);
+npy_cfloat npy_ccoshf(npy_cfloat z);
+npy_cfloat npy_csinhf(npy_cfloat z);
+npy_cfloat npy_ctanhf(npy_cfloat z);
+npy_cfloat npy_cacosf(npy_cfloat z);
+npy_cfloat npy_casinf(npy_cfloat z);
+npy_cfloat npy_catanf(npy_cfloat z);
+npy_cfloat npy_cacoshf(npy_cfloat z);
+npy_cfloat npy_casinhf(npy_cfloat z);
+npy_cfloat npy_catanhf(npy_cfloat z);
+ * Extended precision complex functions
+npy_longdouble npy_cabsl(npy_clongdouble z);
+npy_longdouble npy_cargl(npy_clongdouble z);
+npy_clongdouble npy_cexpl(npy_clongdouble z);
+npy_clongdouble npy_clogl(npy_clongdouble z);
+npy_clongdouble npy_cpowl(npy_clongdouble x, npy_clongdouble y);
+npy_clongdouble npy_csqrtl(npy_clongdouble z);
+npy_clongdouble npy_ccosl(npy_clongdouble z);
+npy_clongdouble npy_csinl(npy_clongdouble z);
+npy_clongdouble npy_ctanl(npy_clongdouble z);
+npy_clongdouble npy_ccoshl(npy_clongdouble z);
+npy_clongdouble npy_csinhl(npy_clongdouble z);
+npy_clongdouble npy_ctanhl(npy_clongdouble z);
+npy_clongdouble npy_cacosl(npy_clongdouble z);
+npy_clongdouble npy_casinl(npy_clongdouble z);
+npy_clongdouble npy_catanl(npy_clongdouble z);
+npy_clongdouble npy_cacoshl(npy_clongdouble z);
+npy_clongdouble npy_casinhl(npy_clongdouble z);
+npy_clongdouble npy_catanhl(npy_clongdouble z);
+ * Functions that set the floating point error
+ * status word.
+ * platform-dependent code translates floating point
+ * status to an integer sum of these values
+#define NPY_FPE_DIVIDEBYZERO 1
+#define NPY_FPE_OVERFLOW 2
+#define NPY_FPE_UNDERFLOW 4
+#define NPY_FPE_INVALID 8
+int npy_clear_floatstatus_barrier(char*);
+int npy_get_floatstatus_barrier(char*);
+ * use caution with these - clang and gcc8.1 are known to reorder calls
+ * to this form of the function which can defeat the check. The _barrier
+ * form of the call is preferable, where the argument is
+ * (char*)&local_variable
+int npy_clear_floatstatus(void);
+int npy_get_floatstatus(void);
+void npy_set_floatstatus_divbyzero(void);
+void npy_set_floatstatus_overflow(void);
+void npy_set_floatstatus_underflow(void);
+void npy_set_floatstatus_invalid(void);
+#include "npy_math_internal.h"
+ * This include file is provided for inclusion in Cython *.pyd files where
+ * one would like to define the NPY_NO_DEPRECATED_API macro. It can be
+ * included by
+ * cdef extern from "npy_no_deprecated_api.h": pass
+/* put this check here since there may be multiple includes in C extensions. */
+#if defined(NDARRAYTYPES_H) || defined(_NPY_DEPRECATED_API_H) || \
+ defined(OLD_DEFINES_H)
+#error "npy_no_deprecated_api.h" must be first among numpy includes.
+#define NPY_NO_DEPRECATED_API NPY_API_VERSION
@@ -0,0 +1,30 @@
+#ifndef _NPY_OS_H_
+#define _NPY_OS_H_
+#if defined(linux) || defined(__linux) || defined(__linux__)
+ #define NPY_OS_LINUX
+#elif defined(__FreeBSD__) || defined(__NetBSD__) || \
+ defined(__OpenBSD__) || defined(__DragonFly__)
+ #define NPY_OS_BSD
+ #ifdef __FreeBSD__
+ #define NPY_OS_FREEBSD
+ #elif defined(__NetBSD__)
+ #define NPY_OS_NETBSD
+ #elif defined(__OpenBSD__)
+ #define NPY_OS_OPENBSD
+ #elif defined(__DragonFly__)
+ #define NPY_OS_DRAGONFLY
+#elif defined(sun) || defined(__sun)
+ #define NPY_OS_SOLARIS
+#elif defined(__CYGWIN__)
+ #define NPY_OS_CYGWIN
+#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
+ #define NPY_OS_WIN32
+#elif defined(__APPLE__)
+ #define NPY_OS_DARWIN
+ #define NPY_OS_UNKNOWN
@@ -0,0 +1,46 @@
+#ifndef _NPY_NUMPYCONFIG_H_
+#define _NPY_NUMPYCONFIG_H_
+#include "_numpyconfig.h"
+ * On Mac OS X, because there is only one configuration stage for all the archs
+ * in universal builds, any macro which depends on the arch needs to be
+ * hardcoded
+#ifdef __APPLE__
+ #undef NPY_SIZEOF_LONG
+ #undef NPY_SIZEOF_PY_INTPTR_T
+ #ifdef __LP64__
+ #define NPY_SIZEOF_LONG 8
+ #define NPY_SIZEOF_PY_INTPTR_T 8
+ #define NPY_SIZEOF_LONG 4
+ #define NPY_SIZEOF_PY_INTPTR_T 4
+/**
+ * To help with the NPY_NO_DEPRECATED_API macro, we include API version
+ * numbers for specific versions of NumPy. To exclude all API that was
+ * deprecated as of 1.7, add the following before #including any NumPy
+ * headers:
+#define NPY_1_7_API_VERSION 0x00000007
+#define NPY_1_8_API_VERSION 0x00000008
+#define NPY_1_9_API_VERSION 0x00000008
+#define NPY_1_10_API_VERSION 0x00000008
+#define NPY_1_11_API_VERSION 0x00000008
+#define NPY_1_12_API_VERSION 0x00000008
+#define NPY_1_13_API_VERSION 0x00000008
+#define NPY_1_14_API_VERSION 0x00000008
+#define NPY_1_15_API_VERSION 0x00000008
+#define NPY_1_16_API_VERSION 0x00000008
+#define NPY_1_17_API_VERSION 0x00000008
+#define NPY_1_18_API_VERSION 0x00000008
+#define NPY_1_19_API_VERSION 0x00000008
+#define NPY_1_20_API_VERSION 0x0000000e
@@ -0,0 +1,187 @@
+/* This header is deprecated as of NumPy 1.7 */
+#ifndef OLD_DEFINES_H
+#define OLD_DEFINES_H
+#if defined(NPY_NO_DEPRECATED_API) && NPY_NO_DEPRECATED_API >= NPY_1_7_API_VERSION
+#error The header "old_defines.h" is deprecated as of NumPy 1.7.
+#define NDARRAY_VERSION NPY_VERSION
+#define PyArray_MIN_BUFSIZE NPY_MIN_BUFSIZE
+#define PyArray_MAX_BUFSIZE NPY_MAX_BUFSIZE
+#define PyArray_BUFSIZE NPY_BUFSIZE
+#define PyArray_PRIORITY NPY_PRIORITY
+#define PyArray_SUBTYPE_PRIORITY NPY_PRIORITY
+#define PyArray_NUM_FLOATTYPE NPY_NUM_FLOATTYPE
+#define NPY_MAX PyArray_MAX
+#define NPY_MIN PyArray_MIN
+#define PyArray_TYPES NPY_TYPES
+#define PyArray_BOOL NPY_BOOL
+#define PyArray_BYTE NPY_BYTE
+#define PyArray_UBYTE NPY_UBYTE
+#define PyArray_SHORT NPY_SHORT
+#define PyArray_USHORT NPY_USHORT
+#define PyArray_INT NPY_INT
+#define PyArray_UINT NPY_UINT
+#define PyArray_LONG NPY_LONG
+#define PyArray_ULONG NPY_ULONG
+#define PyArray_LONGLONG NPY_LONGLONG
+#define PyArray_ULONGLONG NPY_ULONGLONG
+#define PyArray_HALF NPY_HALF
+#define PyArray_FLOAT NPY_FLOAT
+#define PyArray_DOUBLE NPY_DOUBLE
+#define PyArray_LONGDOUBLE NPY_LONGDOUBLE
+#define PyArray_CFLOAT NPY_CFLOAT
+#define PyArray_CDOUBLE NPY_CDOUBLE
+#define PyArray_CLONGDOUBLE NPY_CLONGDOUBLE
+#define PyArray_OBJECT NPY_OBJECT
+#define PyArray_STRING NPY_STRING
+#define PyArray_UNICODE NPY_UNICODE
+#define PyArray_VOID NPY_VOID
+#define PyArray_DATETIME NPY_DATETIME
+#define PyArray_TIMEDELTA NPY_TIMEDELTA
+#define PyArray_NTYPES NPY_NTYPES
+#define PyArray_NOTYPE NPY_NOTYPE
+#define PyArray_CHAR NPY_CHAR
+#define PyArray_USERDEF NPY_USERDEF
+#define PyArray_NUMUSERTYPES NPY_NUMUSERTYPES
+#define PyArray_INTP NPY_INTP
+#define PyArray_UINTP NPY_UINTP
+#define PyArray_INT8 NPY_INT8
+#define PyArray_UINT8 NPY_UINT8
+#define PyArray_INT16 NPY_INT16
+#define PyArray_UINT16 NPY_UINT16
+#define PyArray_INT32 NPY_INT32
+#define PyArray_UINT32 NPY_UINT32
+#ifdef NPY_INT64
+#define PyArray_INT64 NPY_INT64
+#define PyArray_UINT64 NPY_UINT64
+#ifdef NPY_INT128
+#define PyArray_INT128 NPY_INT128
+#define PyArray_UINT128 NPY_UINT128
+#ifdef NPY_FLOAT16
+#define PyArray_FLOAT16 NPY_FLOAT16
+#define PyArray_COMPLEX32 NPY_COMPLEX32
+#ifdef NPY_FLOAT80
+#define PyArray_FLOAT80 NPY_FLOAT80
+#define PyArray_COMPLEX160 NPY_COMPLEX160
+#ifdef NPY_FLOAT96
+#define PyArray_FLOAT96 NPY_FLOAT96
+#define PyArray_COMPLEX192 NPY_COMPLEX192
+#ifdef NPY_FLOAT128
+#define PyArray_FLOAT128 NPY_FLOAT128
+#define PyArray_COMPLEX256 NPY_COMPLEX256
+#define PyArray_FLOAT32 NPY_FLOAT32
+#define PyArray_COMPLEX64 NPY_COMPLEX64
+#define PyArray_FLOAT64 NPY_FLOAT64
+#define PyArray_COMPLEX128 NPY_COMPLEX128
+#define PyArray_TYPECHAR NPY_TYPECHAR
+#define PyArray_BOOLLTR NPY_BOOLLTR
+#define PyArray_BYTELTR NPY_BYTELTR
+#define PyArray_UBYTELTR NPY_UBYTELTR
+#define PyArray_SHORTLTR NPY_SHORTLTR
+#define PyArray_USHORTLTR NPY_USHORTLTR
+#define PyArray_INTLTR NPY_INTLTR
+#define PyArray_UINTLTR NPY_UINTLTR
+#define PyArray_LONGLTR NPY_LONGLTR
+#define PyArray_ULONGLTR NPY_ULONGLTR
+#define PyArray_LONGLONGLTR NPY_LONGLONGLTR
+#define PyArray_ULONGLONGLTR NPY_ULONGLONGLTR
+#define PyArray_HALFLTR NPY_HALFLTR
+#define PyArray_FLOATLTR NPY_FLOATLTR
+#define PyArray_DOUBLELTR NPY_DOUBLELTR
+#define PyArray_LONGDOUBLELTR NPY_LONGDOUBLELTR
+#define PyArray_CFLOATLTR NPY_CFLOATLTR
+#define PyArray_CDOUBLELTR NPY_CDOUBLELTR
+#define PyArray_CLONGDOUBLELTR NPY_CLONGDOUBLELTR
+#define PyArray_OBJECTLTR NPY_OBJECTLTR
+#define PyArray_STRINGLTR NPY_STRINGLTR
+#define PyArray_STRINGLTR2 NPY_STRINGLTR2
+#define PyArray_UNICODELTR NPY_UNICODELTR
+#define PyArray_VOIDLTR NPY_VOIDLTR
+#define PyArray_DATETIMELTR NPY_DATETIMELTR
+#define PyArray_TIMEDELTALTR NPY_TIMEDELTALTR
+#define PyArray_CHARLTR NPY_CHARLTR
+#define PyArray_INTPLTR NPY_INTPLTR
+#define PyArray_UINTPLTR NPY_UINTPLTR
+#define PyArray_GENBOOLLTR NPY_GENBOOLLTR
+#define PyArray_SIGNEDLTR NPY_SIGNEDLTR
+#define PyArray_UNSIGNEDLTR NPY_UNSIGNEDLTR
+#define PyArray_FLOATINGLTR NPY_FLOATINGLTR
+#define PyArray_COMPLEXLTR NPY_COMPLEXLTR
+#define PyArray_QUICKSORT NPY_QUICKSORT
+#define PyArray_HEAPSORT NPY_HEAPSORT
+#define PyArray_MERGESORT NPY_MERGESORT
+#define PyArray_SORTKIND NPY_SORTKIND
+#define PyArray_NSORTS NPY_NSORTS
+#define PyArray_NOSCALAR NPY_NOSCALAR
+#define PyArray_BOOL_SCALAR NPY_BOOL_SCALAR
+#define PyArray_INTPOS_SCALAR NPY_INTPOS_SCALAR
+#define PyArray_INTNEG_SCALAR NPY_INTNEG_SCALAR
+#define PyArray_FLOAT_SCALAR NPY_FLOAT_SCALAR
+#define PyArray_COMPLEX_SCALAR NPY_COMPLEX_SCALAR
+#define PyArray_OBJECT_SCALAR NPY_OBJECT_SCALAR
+#define PyArray_SCALARKIND NPY_SCALARKIND
+#define PyArray_NSCALARKINDS NPY_NSCALARKINDS
+#define PyArray_ANYORDER NPY_ANYORDER
+#define PyArray_CORDER NPY_CORDER
+#define PyArray_FORTRANORDER NPY_FORTRANORDER
+#define PyArray_ORDER NPY_ORDER
+#define PyDescr_ISBOOL PyDataType_ISBOOL
+#define PyDescr_ISUNSIGNED PyDataType_ISUNSIGNED
+#define PyDescr_ISSIGNED PyDataType_ISSIGNED
+#define PyDescr_ISINTEGER PyDataType_ISINTEGER
+#define PyDescr_ISFLOAT PyDataType_ISFLOAT
+#define PyDescr_ISNUMBER PyDataType_ISNUMBER
+#define PyDescr_ISSTRING PyDataType_ISSTRING
+#define PyDescr_ISCOMPLEX PyDataType_ISCOMPLEX
+#define PyDescr_ISPYTHON PyDataType_ISPYTHON
+#define PyDescr_ISFLEXIBLE PyDataType_ISFLEXIBLE
+#define PyDescr_ISUSERDEF PyDataType_ISUSERDEF
+#define PyDescr_ISEXTENDED PyDataType_ISEXTENDED
+#define PyDescr_ISOBJECT PyDataType_ISOBJECT
+#define PyDescr_HASFIELDS PyDataType_HASFIELDS
+#define PyArray_LITTLE NPY_LITTLE
+#define PyArray_BIG NPY_BIG
+#define PyArray_NATIVE NPY_NATIVE
+#define PyArray_SWAP NPY_SWAP
+#define PyArray_IGNORE NPY_IGNORE
+#define PyArray_NATBYTE NPY_NATBYTE
+#define PyArray_OPPBYTE NPY_OPPBYTE
+#define PyArray_MAX_ELSIZE NPY_MAX_ELSIZE
+#define PyArray_USE_PYMEM NPY_USE_PYMEM
+#define PyArray_RemoveLargest PyArray_RemoveSmallest
+#define PyArray_UCS4 npy_ucs4
@@ -0,0 +1,25 @@
+#include "arrayobject.h"
+#ifndef REFCOUNT
+# define REFCOUNT NPY_REFCOUNT
+# define MAX_ELSIZE 16
+#define PyArray_UNSIGNED_TYPES
+#define PyArray_SBYTE NPY_BYTE
+#define PyArray_CopyArray PyArray_CopyInto
+#define _PyArray_multiply_list PyArray_MultiplyIntList
+#define PyArray_ISSPACESAVER(m) NPY_FALSE
+#define PyScalarArray_Check PyArray_CheckScalar
+#define OWN_DIMENSIONS 0
+#define OWN_STRIDES 0
+#define SAVESPACE 0
+#define SAVESPACEBIT 0
+#undef import_array
+#define import_array() { if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); } }
+#ifndef _RANDOM_BITGEN_H
+#define _RANDOM_BITGEN_H
+#pragma once
+#include <stddef.h>
+#include <stdbool.h>
+#include <stdint.h>
+/* Must match the declaration in numpy/random/<any>.pxd */
+typedef struct bitgen {
+ void *state;
+ uint64_t (*next_uint64)(void *st);
+ uint32_t (*next_uint32)(void *st);
+ double (*next_double)(void *st);
+ uint64_t (*next_raw)(void *st);
+} bitgen_t;
@@ -0,0 +1,208 @@
+#ifndef _RANDOMDGEN__DISTRIBUTIONS_H_
+#define _RANDOMDGEN__DISTRIBUTIONS_H_
+#include "Python.h"
+#include "numpy/npy_math.h"
+#include "numpy/random/bitgen.h"
+ * 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.
+#ifdef NP_RANDOM_LEGACY
+#define RAND_INT_TYPE long
+#define RAND_INT_MAX LONG_MAX
+#define RAND_INT_TYPE int64_t
+#define RAND_INT_MAX INT64_MAX
+#define DECLDIR __declspec(dllexport)
+#define DECLDIR extern
+#define MIN(x, y) (((x) < (y)) ? x : y)
+#define MAX(x, y) (((x) > (y)) ? x : y)
+#ifndef M_PI
+#define M_PI 3.14159265358979323846264338328
+typedef struct s_binomial_t {
+ int has_binomial; /* !=0: following parameters initialized for binomial */
+ double psave;
+ RAND_INT_TYPE nsave;
+ double r;
+ double q;
+ double fm;
+ RAND_INT_TYPE m;
+ double p1;
+ double xm;
+ double xl;
+ double xr;
+ double c;
+ double laml;
+ double lamr;
+ double p2;
+ double p3;
+ double p4;
+} binomial_t;
+DECLDIR float random_standard_uniform_f(bitgen_t *bitgen_state);
+DECLDIR double random_standard_uniform(bitgen_t *bitgen_state);
+DECLDIR void random_standard_uniform_fill(bitgen_t *, npy_intp, double *);
+DECLDIR void random_standard_uniform_fill_f(bitgen_t *, npy_intp, float *);
+DECLDIR int64_t random_positive_int64(bitgen_t *bitgen_state);
+DECLDIR int32_t random_positive_int32(bitgen_t *bitgen_state);
+DECLDIR int64_t random_positive_int(bitgen_t *bitgen_state);
+DECLDIR uint64_t random_uint(bitgen_t *bitgen_state);
+DECLDIR double random_standard_exponential(bitgen_t *bitgen_state);
+DECLDIR float random_standard_exponential_f(bitgen_t *bitgen_state);
+DECLDIR void random_standard_exponential_fill(bitgen_t *, npy_intp, double *);
+DECLDIR void random_standard_exponential_fill_f(bitgen_t *, npy_intp, float *);
+DECLDIR void random_standard_exponential_inv_fill(bitgen_t *, npy_intp, double *);
+DECLDIR void random_standard_exponential_inv_fill_f(bitgen_t *, npy_intp, float *);
+DECLDIR double random_standard_normal(bitgen_t *bitgen_state);
+DECLDIR float random_standard_normal_f(bitgen_t *bitgen_state);
+DECLDIR void random_standard_normal_fill(bitgen_t *, npy_intp, double *);
+DECLDIR void random_standard_normal_fill_f(bitgen_t *, npy_intp, float *);
+DECLDIR double random_standard_gamma(bitgen_t *bitgen_state, double shape);
+DECLDIR float random_standard_gamma_f(bitgen_t *bitgen_state, float shape);
+DECLDIR double random_normal(bitgen_t *bitgen_state, double loc, double scale);
+DECLDIR double random_gamma(bitgen_t *bitgen_state, double shape, double scale);
+DECLDIR float random_gamma_f(bitgen_t *bitgen_state, float shape, float scale);
+DECLDIR double random_exponential(bitgen_t *bitgen_state, double scale);
+DECLDIR double random_uniform(bitgen_t *bitgen_state, double lower, double range);
+DECLDIR double random_beta(bitgen_t *bitgen_state, double a, double b);
+DECLDIR double random_chisquare(bitgen_t *bitgen_state, double df);
+DECLDIR double random_f(bitgen_t *bitgen_state, double dfnum, double dfden);
+DECLDIR double random_standard_cauchy(bitgen_t *bitgen_state);
+DECLDIR double random_pareto(bitgen_t *bitgen_state, double a);
+DECLDIR double random_weibull(bitgen_t *bitgen_state, double a);
+DECLDIR double random_power(bitgen_t *bitgen_state, double a);
+DECLDIR double random_laplace(bitgen_t *bitgen_state, double loc, double scale);
+DECLDIR double random_gumbel(bitgen_t *bitgen_state, double loc, double scale);
+DECLDIR double random_logistic(bitgen_t *bitgen_state, double loc, double scale);
+DECLDIR double random_lognormal(bitgen_t *bitgen_state, double mean, double sigma);
+DECLDIR double random_rayleigh(bitgen_t *bitgen_state, double mode);
+DECLDIR double random_standard_t(bitgen_t *bitgen_state, double df);
+DECLDIR double random_noncentral_chisquare(bitgen_t *bitgen_state, double df,
+ double nonc);
+DECLDIR double random_noncentral_f(bitgen_t *bitgen_state, double dfnum,
+ double dfden, double nonc);
+DECLDIR double random_wald(bitgen_t *bitgen_state, double mean, double scale);
+DECLDIR double random_vonmises(bitgen_t *bitgen_state, double mu, double kappa);
+DECLDIR double random_triangular(bitgen_t *bitgen_state, double left, double mode,
+ double right);
+DECLDIR RAND_INT_TYPE random_poisson(bitgen_t *bitgen_state, double lam);
+DECLDIR RAND_INT_TYPE random_negative_binomial(bitgen_t *bitgen_state, double n,
+ double p);
+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 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);
+DECLDIR uint64_t random_interval(bitgen_t *bitgen_state, uint64_t max);
+/* Generate random uint64 numbers in closed interval [off, off + rng]. */
+DECLDIR uint64_t random_bounded_uint64(bitgen_t *bitgen_state, uint64_t off,
+ uint64_t rng, uint64_t mask,
+ bool use_masked);
+/* Generate random uint32 numbers in closed interval [off, off + rng]. */
+DECLDIR uint32_t random_buffered_bounded_uint32(bitgen_t *bitgen_state,
+ uint32_t off, uint32_t rng,
+ uint32_t mask, bool use_masked,
+ int *bcnt, uint32_t *buf);
+DECLDIR uint16_t random_buffered_bounded_uint16(bitgen_t *bitgen_state,
+ uint16_t off, uint16_t rng,
+ uint16_t mask, bool use_masked,
+DECLDIR uint8_t random_buffered_bounded_uint8(bitgen_t *bitgen_state, uint8_t off,
+ uint8_t rng, uint8_t mask,
+ bool use_masked, int *bcnt,
+ uint32_t *buf);
+DECLDIR npy_bool random_buffered_bounded_bool(bitgen_t *bitgen_state, npy_bool off,
+ npy_bool rng, npy_bool mask,
+DECLDIR void random_bounded_uint64_fill(bitgen_t *bitgen_state, uint64_t off,
+ uint64_t rng, npy_intp cnt,
+ bool use_masked, uint64_t *out);
+DECLDIR void random_bounded_uint32_fill(bitgen_t *bitgen_state, uint32_t off,
+ uint32_t rng, npy_intp cnt,
+ bool use_masked, uint32_t *out);
+DECLDIR void random_bounded_uint16_fill(bitgen_t *bitgen_state, uint16_t off,
+ uint16_t rng, npy_intp cnt,
+ bool use_masked, uint16_t *out);
+DECLDIR void random_bounded_uint8_fill(bitgen_t *bitgen_state, uint8_t off,
+ uint8_t rng, npy_intp cnt,
+ bool use_masked, uint8_t *out);
+DECLDIR void random_bounded_bool_fill(bitgen_t *bitgen_state, npy_bool off,
+ npy_bool rng, npy_intp cnt,
+ bool use_masked, npy_bool *out);
+DECLDIR void random_multinomial(bitgen_t *bitgen_state, RAND_INT_TYPE n, RAND_INT_TYPE *mnix,
+ double *pix, npy_intp d, binomial_t *binomial);
+/* multivariate hypergeometric, "count" method */
+DECLDIR int random_multivariate_hypergeometric_count(bitgen_t *bitgen_state,
+ int64_t total,
+ size_t num_colors, int64_t *colors,
+ int64_t nsample,
+ size_t num_variates, int64_t *variates);
+/* multivariate hypergeometric, "marginals" method */
+DECLDIR void random_multivariate_hypergeometric_marginals(bitgen_t *bitgen_state,
+/* Common to legacy-distributions.c and distributions.c but not exported */
+RAND_INT_TYPE random_binomial_btpe(bitgen_t *bitgen_state,
+ RAND_INT_TYPE n,
+ double p,
+ binomial_t *binomial);
+RAND_INT_TYPE random_binomial_inversion(bitgen_t *bitgen_state,
+double random_loggam(double x);
+static NPY_INLINE double next_double(bitgen_t *bitgen_state) {
+ return bitgen_state->next_double(bitgen_state->state);
@@ -0,0 +1,333 @@
+=================
+NumPy Ufunc C-API
+ PyUFunc_FromFuncAndData(PyUFuncGenericFunction *func, void
+ **data, char *types, int ntypes, int nin, int
+ nout, int identity, const char *name, const
+ char *doc, int unused)
+ PyUFunc_RegisterLoopForType(PyUFuncObject *ufunc, int
+ usertype, PyUFuncGenericFunction
+ function, const int *arg_types, void
+ *data)
+ PyUFunc_GenericFunction(PyUFuncObject *ufunc, PyObject *args, PyObject
+ *kwds, PyArrayObject **op)
+ PyUFunc_f_f_As_d_d(char **args, npy_intp const *dimensions, npy_intp
+ const *steps, void *func)
+ PyUFunc_d_d(char **args, npy_intp const *dimensions, npy_intp const
+ *steps, void *func)
+ PyUFunc_f_f(char **args, npy_intp const *dimensions, npy_intp const
+ PyUFunc_g_g(char **args, npy_intp const *dimensions, npy_intp const
+ PyUFunc_F_F_As_D_D(char **args, npy_intp const *dimensions, npy_intp
+ PyUFunc_F_F(char **args, npy_intp const *dimensions, npy_intp const
+ PyUFunc_D_D(char **args, npy_intp const *dimensions, npy_intp const
+ PyUFunc_G_G(char **args, npy_intp const *dimensions, npy_intp const
+ PyUFunc_O_O(char **args, npy_intp const *dimensions, npy_intp const
+ PyUFunc_ff_f_As_dd_d(char **args, npy_intp const *dimensions, npy_intp
+ PyUFunc_ff_f(char **args, npy_intp const *dimensions, npy_intp const
+ PyUFunc_dd_d(char **args, npy_intp const *dimensions, npy_intp const
+ PyUFunc_gg_g(char **args, npy_intp const *dimensions, npy_intp const
+ PyUFunc_FF_F_As_DD_D(char **args, npy_intp const *dimensions, npy_intp
+ PyUFunc_DD_D(char **args, npy_intp const *dimensions, npy_intp const
+ PyUFunc_FF_F(char **args, npy_intp const *dimensions, npy_intp const
+ PyUFunc_GG_G(char **args, npy_intp const *dimensions, npy_intp const
+ PyUFunc_OO_O(char **args, npy_intp const *dimensions, npy_intp const
+ PyUFunc_O_O_method(char **args, npy_intp const *dimensions, npy_intp
+ PyUFunc_OO_O_method(char **args, npy_intp const *dimensions, npy_intp
+ PyUFunc_On_Om(char **args, npy_intp const *dimensions, npy_intp const
+ PyUFunc_GetPyValues(char *name, int *bufsize, int *errmask, PyObject
+ **errobj)
+On return, if errobj is populated with a non-NULL value, the caller
+owns a new reference to errobj.
+ PyUFunc_checkfperr(int errmask, PyObject *errobj, int *first)
+ PyUFunc_clearfperr()
+ PyUFunc_getfperr(void )
+ PyUFunc_handlefperr(int errmask, PyObject *errobj, int retstatus, int
+ *first)
+ PyUFunc_ReplaceLoopBySignature(PyUFuncObject
+ *func, PyUFuncGenericFunction
+ newfunc, const int
+ *signature, PyUFuncGenericFunction
+ *oldfunc)
+ PyUFunc_FromFuncAndDataAndSignature(PyUFuncGenericFunction *func, void
+ **data, char *types, int
+ ntypes, int nin, int nout, int
+ identity, const char *name, const
+ char *doc, int unused, const char
+ *signature)
+ PyUFunc_SetUsesArraysAsData(void **data, size_t i)
+ PyUFunc_e_e(char **args, npy_intp const *dimensions, npy_intp const
+ PyUFunc_e_e_As_f_f(char **args, npy_intp const *dimensions, npy_intp
+ PyUFunc_e_e_As_d_d(char **args, npy_intp const *dimensions, npy_intp
+ PyUFunc_ee_e(char **args, npy_intp const *dimensions, npy_intp const
+ PyUFunc_ee_e_As_ff_f(char **args, npy_intp const *dimensions, npy_intp
+ PyUFunc_ee_e_As_dd_d(char **args, npy_intp const *dimensions, npy_intp
+ PyUFunc_DefaultTypeResolver(PyUFuncObject *ufunc, NPY_CASTING
+ casting, PyArrayObject
+ **operands, PyObject
+ *type_tup, PyArray_Descr **out_dtypes)
+This function applies the default type resolution rules
+for the provided ufunc.
+ PyUFunc_ValidateCasting(PyUFuncObject *ufunc, NPY_CASTING
+ **operands, PyArray_Descr **dtypes)
+Validates that the input operands can be cast to
+the input types, and the output types can be cast to
+the output operands where provided.
+Returns 0 on success, -1 (with exception raised) on validation failure.
+ PyUFunc_RegisterLoopForDescr(PyUFuncObject *ufunc, PyArray_Descr
+ *user_dtype, PyUFuncGenericFunction
+ function, PyArray_Descr
+ **arg_dtypes, void *data)
+ PyUFunc_FromFuncAndDataAndSignatureAndIdentity(PyUFuncGenericFunction
+ *func, void
+ **data, char
+ *types, int ntypes, int
+ nin, int nout, int
+ identity, const char
+ *name, const char
+ *doc, const int
+ unused, const char
+ *signature, PyObject
+ *identity_value)
@@ -0,0 +1,369 @@
+#ifndef Py_UFUNCOBJECT_H
+#define Py_UFUNCOBJECT_H
+ * The legacy generic inner loop for a standard element-wise or
+ * generalized ufunc.
+typedef void (*PyUFuncGenericFunction)
+ (char **args,
+ npy_intp const *dimensions,
+ npy_intp const *strides,
+ void *innerloopdata);
+ * The most generic one-dimensional inner loop for
+ * a masked standard element-wise ufunc. "Masked" here means that it skips
+ * doing calculations on any items for which the maskptr array has a true
+ * value.
+typedef void (PyUFunc_MaskedStridedInnerLoopFunc)(
+ char **dataptrs, npy_intp *strides,
+ char *maskptr, npy_intp mask_stride,
+ npy_intp count,
+ NpyAuxData *innerloopdata);
+/* Forward declaration for the type resolver and loop selector typedefs */
+struct _tagPyUFuncObject;
+ * Given the operands for calling a ufunc, should determine the
+ * calculation input and output data types and return an inner loop function.
+ * This function should validate that the casting rule is being followed,
+ * and fail if it is not.
+ * For backwards compatibility, the regular type resolution function does not
+ * support auxiliary data with object semantics. The type resolution call
+ * which returns a masked generic function returns a standard NpyAuxData
+ * object, for which the NPY_AUXDATA_FREE and NPY_AUXDATA_CLONE macros
+ * work.
+ * ufunc: The ufunc object.
+ * casting: The 'casting' parameter provided to the ufunc.
+ * operands: An array of length (ufunc->nin + ufunc->nout),
+ * with the output parameters possibly NULL.
+ * type_tup: Either NULL, or the type_tup passed to the ufunc.
+ * out_dtypes: An array which should be populated with new
+ * references to (ufunc->nin + ufunc->nout) new
+ * dtypes, one for each input and output. These
+ * dtypes should all be in native-endian format.
+ * Should return 0 on success, -1 on failure (with exception set),
+ * or -2 if Py_NotImplemented should be returned.
+typedef int (PyUFunc_TypeResolutionFunc)(
+ struct _tagPyUFuncObject *ufunc,
+ NPY_CASTING casting,
+ PyArrayObject **operands,
+ PyObject *type_tup,
+ 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.
+ * 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
+ * be passed into the out_innerloop function.
+ * out_needs_api: If the inner loop needs to use the Python API,
+ * should set the to 1, otherwise should leave
+ * this untouched.
+typedef int (PyUFunc_LegacyInnerLoopSelectionFunc)(
+ PyArray_Descr **dtypes,
+ PyUFuncGenericFunction *out_innerloop,
+ void **out_innerloopdata,
+ int *out_needs_api);
+typedef int (PyUFunc_MaskedInnerLoopSelectionFunc)(
+ PyArray_Descr *mask_dtype,
+ npy_intp *fixed_strides,
+ npy_intp fixed_mask_stride,
+ PyUFunc_MaskedStridedInnerLoopFunc **out_innerloop,
+ NpyAuxData **out_innerloopdata,
+typedef struct _tagPyUFuncObject {
+ * nin: Number of inputs
+ * nout: Number of outputs
+ * nargs: Always nin + nout (Why is it stored?)
+ int nin, nout, nargs;
+ * Identity for reduction, any of PyUFunc_One, PyUFunc_Zero
+ * PyUFunc_MinusOne, PyUFunc_None, PyUFunc_ReorderableNone,
+ * PyUFunc_IdentityValue.
+ int identity;
+ /* Array of one-dimensional core loops */
+ PyUFuncGenericFunction *functions;
+ /* Array of funcdata that gets passed into the functions */
+ void **data;
+ /* The number of elements in 'functions' and 'data' */
+ int ntypes;
+ /* Used to be unused field 'check_return' */
+ int reserved1;
+ /* The name of the ufunc */
+ const char *name;
+ /* Array of type numbers, of size ('nargs' * 'ntypes') */
+ char *types;
+ /* Documentation string */
+ const char *doc;
+ PyObject *obj;
+ PyObject *userloops;
+ /* generalized ufunc parameters */
+ /* 0 for scalar ufunc; 1 for generalized ufunc */
+ int core_enabled;
+ /* number of distinct dimension names in signature */
+ int core_num_dim_ix;
+ * dimension indices of input/output argument k are stored in
+ * core_dim_ixs[core_offsets[k]..core_offsets[k]+core_num_dims[k]-1]
+ /* numbers of core dimensions of each argument */
+ int *core_num_dims;
+ * dimension indices in a flatted form; indices
+ * are in the range of [0,core_num_dim_ix)
+ int *core_dim_ixs;
+ * positions of 1st core dimensions of each
+ * argument in core_dim_ixs, equivalent to cumsum(core_num_dims)
+ int *core_offsets;
+ /* signature string for printing purpose */
+ char *core_signature;
+ * A function which resolves the types and fills an array
+ * with the dtypes for the inputs and outputs.
+ PyUFunc_TypeResolutionFunc *type_resolver;
+ * A function which returns an inner loop written for
+ * NumPy 1.6 and earlier ufuncs. This is for backwards
+ * compatibility, and may be NULL if inner_loop_selector
+ * is specified.
+ PyUFunc_LegacyInnerLoopSelectionFunc *legacy_inner_loop_selector;
+ * This was blocked off to be the "new" inner loop selector in 1.7,
+ * but this was never implemented. (This is also why the above
+ * selector is called the "legacy" selector.)
+ void *reserved2;
+ * A function which returns a masked inner loop for the ufunc.
+ PyUFunc_MaskedInnerLoopSelectionFunc *masked_inner_loop_selector;
+ * List of flags for each operand when ufunc is called by nditer object.
+ * These flags will be used in addition to the default flags for each
+ * operand set by nditer object.
+ npy_uint32 *op_flags;
+ * List of global flags used when ufunc is called by nditer object.
+ * These flags will be used in addition to the default global flags
+ * set by nditer object.
+ npy_uint32 iter_flags;
+ /* New in NPY_API_VERSION 0x0000000D and above */
+ * for each core_num_dim_ix distinct dimension names,
+ * the possible "frozen" size (-1 if not frozen).
+ npy_intp *core_dim_sizes;
+ * for each distinct core dimension, a set of UFUNC_CORE_DIM* flags
+ npy_uint32 *core_dim_flags;
+ /* Identity for reduction, when identity == PyUFunc_IdentityValue */
+ PyObject *identity_value;
+} PyUFuncObject;
+/* Generalized ufunc; 0x0001 reserved for possible use as CORE_ENABLED */
+/* the core dimension's size will be determined by the operands. */
+#define UFUNC_CORE_DIM_SIZE_INFERRED 0x0002
+/* the core dimension may be absent */
+#define UFUNC_CORE_DIM_CAN_IGNORE 0x0004
+/* flags inferred during execution */
+#define UFUNC_CORE_DIM_MISSING 0x00040000
+#define UFUNC_ERR_IGNORE 0
+#define UFUNC_ERR_WARN 1
+#define UFUNC_ERR_RAISE 2
+#define UFUNC_ERR_CALL 3
+#define UFUNC_ERR_PRINT 4
+#define UFUNC_ERR_LOG 5
+ /* Python side integer mask */
+#define UFUNC_MASK_DIVIDEBYZERO 0x07
+#define UFUNC_MASK_OVERFLOW 0x3f
+#define UFUNC_MASK_UNDERFLOW 0x1ff
+#define UFUNC_MASK_INVALID 0xfff
+#define UFUNC_SHIFT_DIVIDEBYZERO 0
+#define UFUNC_SHIFT_OVERFLOW 3
+#define UFUNC_SHIFT_UNDERFLOW 6
+#define UFUNC_SHIFT_INVALID 9
+#define UFUNC_OBJ_ISOBJECT 1
+#define UFUNC_OBJ_NEEDS_API 2
+ /* Default user error mode */
+#define UFUNC_ERR_DEFAULT \
+ (UFUNC_ERR_WARN << UFUNC_SHIFT_DIVIDEBYZERO) + \
+ (UFUNC_ERR_WARN << UFUNC_SHIFT_OVERFLOW) + \
+ (UFUNC_ERR_WARN << UFUNC_SHIFT_INVALID)
+#define NPY_LOOP_BEGIN_THREADS do {if (!(loop->obj & UFUNC_OBJ_NEEDS_API)) _save = PyEval_SaveThread();} while (0);
+#define NPY_LOOP_END_THREADS do {if (!(loop->obj & UFUNC_OBJ_NEEDS_API)) PyEval_RestoreThread(_save);} while (0);
+#define NPY_LOOP_BEGIN_THREADS
+#define NPY_LOOP_END_THREADS
+ * UFunc has unit of 0, and the order of operations can be reordered
+ * This case allows reduction with multiple axes at once.
+#define PyUFunc_Zero 0
+ * UFunc has unit of 1, and the order of operations can be reordered
+#define PyUFunc_One 1
+ * UFunc has unit of -1, and the order of operations can be reordered
+ * This case allows reduction with multiple axes at once. Intended for
+ * bitwise_and reduction.
+#define PyUFunc_MinusOne 2
+ * UFunc has no unit, and the order of operations cannot be reordered.
+ * This case does not allow reduction with multiple axes at once.
+#define PyUFunc_None -1
+ * UFunc has no unit, and the order of operations can be reordered
+#define PyUFunc_ReorderableNone -2
+ * UFunc unit is an identity_value, and the order of operations can be reordered
+#define PyUFunc_IdentityValue -3
+#define UFUNC_REDUCE 0
+#define UFUNC_ACCUMULATE 1
+#define UFUNC_REDUCEAT 2
+#define UFUNC_OUTER 3
+ int nin;
+ int nout;
+ PyObject *callable;
+} PyUFunc_PyFuncData;
+/* A linked-list of function information for
+ user-defined 1-d loops.
+typedef struct _loop1d_info {
+ PyUFuncGenericFunction func;
+ void *data;
+ int *arg_types;
+ struct _loop1d_info *next;
+ int nargs;
+ PyArray_Descr **arg_dtypes;
+} PyUFunc_Loop1d;
+#include "__ufunc_api.h"
+#define UFUNC_PYVALS_NAME "UFUNC_PYVALS"
+ * THESE MACROS ARE DEPRECATED.
+ * Use npy_set_floatstatus_* in the npymath library.
+#define UFUNC_FPE_DIVIDEBYZERO NPY_FPE_DIVIDEBYZERO
+#define UFUNC_FPE_OVERFLOW NPY_FPE_OVERFLOW
+#define UFUNC_FPE_UNDERFLOW NPY_FPE_UNDERFLOW
+#define UFUNC_FPE_INVALID NPY_FPE_INVALID
+#define generate_divbyzero_error() npy_set_floatstatus_divbyzero()
+#define generate_overflow_error() npy_set_floatstatus_overflow()
+ /* Make sure it gets defined if it isn't already */
+#ifndef UFUNC_NOFPE
+/* Clear the floating point exception default of Borland C++ */
+#if defined(__BORLANDC__)
+#define UFUNC_NOFPE _control87(MCW_EM, MCW_EM);
+#define UFUNC_NOFPE
+#endif /* !Py_UFUNCOBJECT_H */
@@ -0,0 +1,37 @@
+#ifndef __NUMPY_UTILS_HEADER__
+#define __NUMPY_UTILS_HEADER__
+#ifndef __COMP_NPY_UNUSED
+ #if defined(__GNUC__)
+ #define __COMP_NPY_UNUSED __attribute__ ((__unused__))
+ #elif defined(__ICC)
+ #elif defined(__clang__)
+ #define __COMP_NPY_UNUSED __attribute__ ((unused))
+ #define __COMP_NPY_UNUSED
+#if defined(__GNUC__) || defined(__ICC) || defined(__clang__)
+ #define NPY_DECL_ALIGNED(x) __attribute__ ((aligned (x)))
+#elif defined(_MSC_VER)
+ #define NPY_DECL_ALIGNED(x) __declspec(align(x))
+ #define NPY_DECL_ALIGNED(x)
+/* Use this to tag a variable as not used. It will remove unused variable
+ * warning on support platforms (see __COM_NPY_UNUSED) and mangle the variable
+ * to avoid accidental use */
+#define NPY_UNUSED(x) (__NPY_UNUSED_TAGGED ## x) __COMP_NPY_UNUSED
+#define NPY_EXPAND(x) x
+#define NPY_STRINGIFY(x) #x
+#define NPY_TOSTRING(x) NPY_STRINGIFY(x)
+#define NPY_CAT__(a, b) a ## b
+#define NPY_CAT_(a, b) NPY_CAT__(a, b)
+#define NPY_CAT(a, b) NPY_CAT_(a, b)
@@ -0,0 +1,12 @@
+[meta]
+Name = mlib
+Description = Math library used with this version of numpy
+Version = 1.0
+[default]
+Libs=
+Cflags=
+[msvc]
+Name=npymath
+Description=Portable, core math library implementing C99 standard
+Version=0.1
+[variables]
+pkgname=numpy.core
+prefix=${pkgdir}
+libdir=${prefix}\lib
+includedir=${prefix}\include
+Libs=-L${libdir} -lnpymath
+Cflags=-I${includedir}
+Requires=mlib
+Libs=/LIBPATH:${libdir} npymath.lib
+Cflags=/INCLUDE:${includedir}
+Machine arithmetics - determine the parameters of the
+floating-point arithmetic system
+Author: Pearu Peterson, September 2003
+__all__ = ['MachAr']
+from numpy.core.fromnumeric import any
+from numpy.core._ufunc_config import errstate
+# Need to speed this up...especially for longfloat
+class MachAr:
+ Diagnosing machine parameters.
+ ibeta : int
+ Radix in which numbers are represented.
+ it : int
+ Number of base-`ibeta` digits in the floating point mantissa M.
+ Exponent of the smallest (most negative) power of `ibeta` that,
+ added to 1.0, gives something different from 1.0
+ Floating-point number ``beta**machep`` (floating point precision)
+ Exponent of the smallest power of `ibeta` that, subtracted
+ from 1.0, gives something different from 1.0.
+ Floating-point number ``beta**negep``.
+ Number of bits in the exponent (including its sign and bias).
+ Smallest (most negative) power of `ibeta` consistent with there
+ being no leading zeros in the mantissa.
+ xmin : float
+ Floating-point number ``beta**minexp`` (the smallest [in
+ magnitude] positive floating point number with full precision).
+ Smallest (positive) power of `ibeta` that causes overflow.
+ xmax : float
+ ``(1-epsneg) * beta**maxexp`` (the largest [in magnitude]
+ usable floating value).
+ irnd : int
+ In ``range(6)``, information on what kind of rounding is done
+ in addition, and on how underflow is handled.
+ ngrd : int
+ Number of 'guard digits' used when truncating the product
+ of two mantissas to fit the representation.
+ epsilon : float
+ Same as `eps`.
+ Same as `xmin`.
+ huge : float
+ Same as `xmax`.
+ precision : float
+ ``- int(-log10(eps))``
+ resolution : float
+ ``- 10**(-precision)``
+ float_conv : function, optional
+ Function that converts an integer or integer array to a float
+ or float array. Default is `float`.
+ int_conv : function, optional
+ Function that converts a float or float array to an integer or
+ integer array. Default is `int`.
+ float_to_float : function, optional
+ Function that converts a float array to float. Default is `float`.
+ Note that this does not seem to do anything useful in the current
+ implementation.
+ float_to_str : function, optional
+ Function that converts a single float to a string. Default is
+ ``lambda v:'%24.16e' %v``.
+ title : str, optional
+ Title that is printed in the string representation of `MachAr`.
+ finfo : Machine limits for floating point types.
+ iinfo : Machine limits for integer types.
+ .. [1] Press, Teukolsky, Vetterling and Flannery,
+ "Numerical Recipes in C++," 2nd ed,
+ Cambridge University Press, 2002, p. 31.
+ def __init__(self, float_conv=float,int_conv=int,
+ float_to_float=float,
+ float_to_str=lambda v:'%24.16e' % v,
+ title='Python floating point number'):
+ float_conv - convert integer to float (array)
+ int_conv - convert float (array) to integer
+ float_to_float - convert float array to float
+ float_to_str - convert array float to str
+ title - description of used floating point numbers
+ # We ignore all errors here because we are purposely triggering
+ # underflow to detect the properties of the runninng arch.
+ with errstate(under='ignore'):
+ self._do_init(float_conv, int_conv, float_to_float, float_to_str, title)
+ def _do_init(self, float_conv, int_conv, float_to_float, float_to_str, title):
+ max_iterN = 10000
+ msg = "Did not converge after %d tries with %s"
+ one = float_conv(1)
+ two = one + one
+ zero = one - one
+ # Do we really need to do this? Aren't they 2 and 2.0?
+ # Determine ibeta and beta
+ a = one
+ for _ in range(max_iterN):
+ a = a + a
+ temp = a + one
+ temp1 = temp - a
+ if any(temp1 - one != zero):
+ raise RuntimeError(msg % (_, one.dtype))
+ b = one
+ b = b + b
+ temp = a + b
+ itemp = int_conv(temp-a)
+ if any(itemp != 0):
+ ibeta = itemp
+ beta = float_conv(ibeta)
+ # Determine it and irnd
+ it = -1
+ it = it + 1
+ b = b * beta
+ temp = b + one
+ temp1 = temp - b
+ betah = beta / two
+ temp = a + betah
+ irnd = 0
+ if any(temp-a != zero):
+ irnd = 1
+ tempa = a + beta
+ temp = tempa + betah
+ if irnd == 0 and any(temp-tempa != zero):
+ irnd = 2
+ # Determine negep and epsneg
+ negep = it + 3
+ betain = one / beta
+ for i in range(negep):
+ a = a * betain
+ b = a
+ temp = one - a
+ if any(temp-one != zero):
+ a = a * beta
+ negep = negep - 1
+ # Prevent infinite loop on PPC with gcc 4.0:
+ if negep < 0:
+ raise RuntimeError("could not determine machine tolerance "
+ "for 'negep', locals() -> %s" % (locals()))
+ negep = -negep
+ epsneg = a
+ # Determine machep and eps
+ machep = - it - 3
+ a = b
+ temp = one + a
+ machep = machep + 1
+ eps = a
+ # Determine ngrd
+ ngrd = 0
+ temp = one + eps
+ if irnd == 0 and any(temp*one - one != zero):
+ ngrd = 1
+ # Determine iexp
+ k = 1
+ z = betain
+ t = one + eps
+ nxres = 0
+ y = z
+ z = y*y
+ a = z*one # Check here for underflow
+ temp = z*t
+ if any(a+a == zero) or any(abs(z) >= y):
+ temp1 = temp * betain
+ if any(temp1*beta == z):
+ k = k + k
+ if ibeta != 10:
+ iexp = i + 1
+ mx = k + k
+ iexp = 2
+ iz = ibeta
+ while k >= iz:
+ iz = iz * ibeta
+ iexp = iexp + 1
+ mx = iz + iz - 1
+ # Determine minexp and xmin
+ xmin = y
+ y = y * betain
+ a = y * one
+ temp = y * t
+ if any((a + a) != zero) and any(abs(y) < xmin):
+ k = k + 1
+ if any(temp1*beta == y) and any(temp != y):
+ nxres = 3
+ minexp = -k
+ # Determine maxexp, xmax
+ if mx <= k + k - 3 and ibeta != 10:
+ mx = mx + mx
+ maxexp = mx + minexp
+ irnd = irnd + nxres
+ if irnd >= 2:
+ maxexp = maxexp - 2
+ i = maxexp + minexp
+ if ibeta == 2 and not i:
+ maxexp = maxexp - 1
+ if i > 20:
+ if any(a != y):
+ xmax = one - epsneg
+ if any(xmax*one != xmax):
+ xmax = one - beta*epsneg
+ xmax = xmax / (xmin*beta*beta*beta)
+ i = maxexp + minexp + 3
+ for j in range(i):
+ if ibeta == 2:
+ xmax = xmax + xmax
+ xmax = xmax * beta
+ self.ibeta = ibeta
+ self.it = it
+ self.negep = negep
+ self._str_epsneg = float_to_str(epsneg)
+ self.machep = machep
+ self.eps = float_to_float(eps)
+ self._str_eps = float_to_str(eps)
+ self.ngrd = ngrd
+ self.iexp = iexp
+ self.minexp = minexp
+ self.xmin = float_to_float(xmin)
+ self._str_xmin = float_to_str(xmin)
+ self.maxexp = maxexp
+ self.xmax = float_to_float(xmax)
+ self._str_xmax = float_to_str(xmax)
+ self.irnd = irnd
+ self.title = title
+ # Commonly used parameters
+ self.epsilon = self.eps
+ self.tiny = self.xmin
+ self.huge = self.xmax
+ import math
+ self.precision = int(-math.log10(float_to_float(self.eps)))
+ ten = two + two + two + two + two
+ resolution = ten ** (-self.precision)
+ self.resolution = float_to_float(resolution)
+ self._str_resolution = float_to_str(resolution)
+ 'Machine parameters for %(title)s\n'
+ '---------------------------------------------------------------------\n'
+ 'ibeta=%(ibeta)s it=%(it)s iexp=%(iexp)s ngrd=%(ngrd)s irnd=%(irnd)s\n'
+ 'machep=%(machep)s eps=%(_str_eps)s (beta**machep == epsilon)\n'
+ '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'
+ print(MachAr())
@@ -0,0 +1,337 @@
+from .numeric import uint8, ndarray, dtype
+from numpy.compat import (
+ os_fspath, contextlib_nullcontext, is_pathlib_path
+__all__ = ['memmap']
+dtypedescr = dtype
+valid_filemodes = ["r", "c", "r+", "w+"]
+writeable_filemodes = ["r+", "w+"]
+mode_equivalents = {
+ "readonly":"r",
+ "copyonwrite":"c",
+ "readwrite":"r+",
+ "write":"w+"
+class memmap(ndarray):
+ """Create a memory-map to an array stored in a *binary* file on disk.
+ Memory-mapped files are used for accessing small segments of large files
+ on disk, without reading the entire file into memory. NumPy's
+ memmap's are array-like objects. This differs from Python's ``mmap``
+ module, which uses file-like objects.
+ This subclass of ndarray has some unpleasant interactions with
+ some operations, because it doesn't quite fit properly as a subclass.
+ An alternative to using this subclass is to create the ``mmap``
+ object yourself, then create an ndarray with ndarray.__new__ directly,
+ passing the object created in its 'buffer=' parameter.
+ This class may at some point be turned into a factory function
+ 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
+ resource is actually closed, since it may be shared between different
+ memmap instances.
+ filename : str, file-like object, or pathlib.Path instance
+ The file name or file object to be used as the array data buffer.
+ The data-type used to interpret the file contents.
+ Default is `uint8`.
+ mode : {'r+', 'r', 'w+', 'c'}, optional
+ The file is opened in this mode:
+ +------+-------------------------------------------------------------+
+ | 'r' | Open existing file for reading only. |
+ | 'r+' | Open existing file for reading and writing. |
+ | 'w+' | Create or overwrite existing file for reading and writing. |
+ | 'c' | Copy-on-write: assignments affect data in memory, but |
+ | | changes are not saved to disk. The file on disk is |
+ | | read-only. |
+ Default is 'r+'.
+ In the file, array data starts at this offset. Since `offset` is
+ measured in bytes, it should normally be a multiple of the byte-size
+ of `dtype`. When ``mode != 'r'``, even positive offsets beyond end of
+ file are valid; The file will be extended to accommodate the
+ additional data. By default, ``memmap`` will start at the beginning of
+ the file, even if ``filename`` is a file pointer ``fp`` and
+ ``fp.tell() != 0``.
+ shape : tuple, optional
+ The desired shape of the array. If ``mode == 'r'`` and the number
+ of remaining bytes after `offset` is not a multiple of the byte-size
+ of `dtype`, you must specify `shape`. By default, the returned array
+ will be 1-D with the number of elements determined by file size
+ and data-type.
+ Specify the order of the ndarray memory layout:
+ :term:`row-major`, C-style or :term:`column-major`,
+ Fortran-style. This only has an effect if the shape is
+ greater than 1-D. The default order is 'C'.
+ filename : str or pathlib.Path instance
+ Path to the mapped file.
+ Offset position in the file.
+ mode : str
+ File mode.
+ flush
+ Flush any changes in memory to file on disk.
+ When you delete a memmap object, flush is called first to write
+ changes to disk.
+ lib.format.open_memmap : Create or load a memory-mapped ``.npy`` file.
+ 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
+ current size in the filesystem, the contents of the new part are
+ unspecified. On systems with POSIX filesystem semantics, the extended
+ part will be filled with zero bytes.
+ >>> data = np.arange(12, dtype='float32')
+ >>> data.resize((3,4))
+ This example uses a temporary file so that doctest doesn't write
+ files to your directory. You would use a 'normal' filename.
+ >>> from tempfile import mkdtemp
+ >>> import os.path as path
+ >>> filename = path.join(mkdtemp(), 'newfile.dat')
+ Create a memmap with dtype and shape that matches our data:
+ >>> fp = np.memmap(filename, dtype='float32', mode='w+', shape=(3,4))
+ >>> fp
+ memmap([[0., 0., 0., 0.],
+ [0., 0., 0., 0.],
+ [0., 0., 0., 0.]], dtype=float32)
+ Write data to memmap array:
+ >>> fp[:] = data[:]
+ memmap([[ 0., 1., 2., 3.],
+ [ 8., 9., 10., 11.]], dtype=float32)
+ >>> fp.filename == path.abspath(filename)
+ Flushes memory changes to disk in order to read them back
+ >>> fp.flush()
+ Load the memmap and verify data was stored:
+ >>> newfp = np.memmap(filename, dtype='float32', mode='r', shape=(3,4))
+ >>> newfp
+ Read-only memmap:
+ >>> fpr = np.memmap(filename, dtype='float32', mode='r', shape=(3,4))
+ >>> fpr.flags.writeable
+ Copy-on-write memmap:
+ >>> fpc = np.memmap(filename, dtype='float32', mode='c', shape=(3,4))
+ >>> fpc.flags.writeable
+ It's possible to assign to copy-on-write array, but values are only
+ written into the memory copy of the array, and not written to disk:
+ >>> fpc
+ >>> fpc[0,:] = 0
+ memmap([[ 0., 0., 0., 0.],
+ File on disk is unchanged:
+ >>> fpr
+ Offset into a memmap:
+ >>> fpo = np.memmap(filename, dtype='float32', mode='r', offset=16)
+ >>> fpo
+ memmap([ 4., 5., 6., 7., 8., 9., 10., 11.], dtype=float32)
+ __array_priority__ = -100.0
+ def __new__(subtype, filename, dtype=uint8, mode='r+', offset=0,
+ shape=None, order='C'):
+ # Import here to minimize 'import numpy' overhead
+ import mmap
+ import os.path
+ mode = mode_equivalents[mode]
+ if mode not in valid_filemodes:
+ "mode must be one of {!r} (got {!r})"
+ .format(valid_filemodes + list(mode_equivalents.keys()), mode)
+ if mode == 'w+' and shape is None:
+ raise ValueError("shape must be given")
+ if hasattr(filename, 'read'):
+ f_ctx = contextlib_nullcontext(filename)
+ f_ctx = open(os_fspath(filename), ('r' if mode == 'c' else mode)+'b')
+ with f_ctx as fid:
+ fid.seek(0, 2)
+ flen = fid.tell()
+ descr = dtypedescr(dtype)
+ _dbytes = descr.itemsize
+ if shape is None:
+ bytes = flen - offset
+ if bytes % _dbytes:
+ raise ValueError("Size of available data is not a "
+ "multiple of the data-type size.")
+ size = bytes // _dbytes
+ shape = (size,)
+ if not isinstance(shape, tuple):
+ shape = (shape,)
+ size = np.intp(1) # avoid default choice of np.int_, which might overflow
+ for k in shape:
+ size *= k
+ bytes = int(offset + size*_dbytes)
+ if mode in ('w+', 'r+') and flen < bytes:
+ fid.seek(bytes - 1, 0)
+ fid.write(b'\0')
+ fid.flush()
+ if mode == 'c':
+ acc = mmap.ACCESS_COPY
+ elif mode == 'r':
+ acc = mmap.ACCESS_READ
+ acc = mmap.ACCESS_WRITE
+ start = offset - offset % mmap.ALLOCATIONGRANULARITY
+ bytes -= start
+ array_offset = offset - start
+ mm = mmap.mmap(fid.fileno(), bytes, access=acc, offset=start)
+ self = ndarray.__new__(subtype, shape, dtype=descr, buffer=mm,
+ offset=array_offset, order=order)
+ self._mmap = mm
+ self.offset = offset
+ self.mode = mode
+ if is_pathlib_path(filename):
+ # special case - if we were constructed with a pathlib.path,
+ # then filename is a path object, not a string
+ self.filename = filename.resolve()
+ elif hasattr(fid, "name") and isinstance(fid.name, str):
+ # py3 returns int for TemporaryFile().name
+ self.filename = os.path.abspath(fid.name)
+ # same as memmap copies (e.g. memmap + 1)
+ self.filename = None
+ if hasattr(obj, '_mmap') and np.may_share_memory(self, obj):
+ self._mmap = obj._mmap
+ self.filename = obj.filename
+ self.offset = obj.offset
+ self.mode = obj.mode
+ self._mmap = None
+ self.offset = None
+ self.mode = None
+ def flush(self):
+ Write any changes in the array to the file on disk.
+ For further information, see `memmap`.
+ memmap
+ if self.base is not None and hasattr(self.base, 'flush'):
+ self.base.flush()
+ def __array_wrap__(self, arr, context=None):
+ arr = super(memmap, self).__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
+ # to keep original memmap subclasses behavior
+ if self is arr or type(self) is not memmap:
+ # Return scalar instead of 0d memmap, e.g. for np.sum with
+ # axis=None
+ if arr.shape == ():
+ return arr[()]
+ # Return ndarray otherwise
+ return arr.view(np.ndarray)
+ def __getitem__(self, index):
+ res = super(memmap, self).__getitem__(index)
+ if type(res) is memmap and res._mmap is None:
+ return res.view(type=ndarray)
@@ -0,0 +1,1673 @@
+Create the numpy.core.multiarray namespace for backward compatibility. In v1.16
+the multiarray and umath c-extension modules were merged into a single
+_multiarray_umath extension module. So we replicate the old namespace
+by importing from the extension module.
+from . import _multiarray_umath
+from ._multiarray_umath import * # noqa: F403
+# These imports are needed for backward compatibility,
+# do not change them. issue gh-15518
+# _get_ndarray_c_version is semi-public, on purpose not added to __all__
+from ._multiarray_umath import (
+ _fastCopyAndTranspose, _flagdict, _insert, _reconstruct, _vec_string,
+ _ARRAY_API, _monotonicity, _get_ndarray_c_version, _set_madvise_hugepage,
+ '_ARRAY_API', 'ALLOW_THREADS', 'BUFSIZE', 'CLIP', 'DATETIMEUNITS',
+ 'ITEM_HASOBJECT', 'ITEM_IS_POINTER', 'LIST_PICKLE', 'MAXDIMS',
+ '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',
+ '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',
+ 'empty', 'empty_like', 'error', 'flagsobj', 'flatiter', 'format_longfloat',
+ 'frombuffer', 'fromfile', 'fromiter', 'fromstring', 'inner',
+ 'interp', 'interp_complex', 'is_busday', 'lexsort',
+ 'matmul', 'may_share_memory', 'min_scalar_type', 'ndarray', 'nditer',
+ 'nested_iters', 'normalize_axis_index', 'packbits',
+ 'promote_types', 'putmask', 'ravel_multi_index', 'result_type', 'scalar',
+ 'set_datetimeparse_function', 'set_legacy_print_mode', 'set_numeric_ops',
+ 'set_string_function', 'set_typeDict', 'shares_memory',
+ 'tracemalloc_domain', 'typeinfo', 'unpackbits', 'unravel_index', 'vdot',
+ 'where', 'zeros']
+# For backward compatibility, make sure pickle imports these functions from here
+_reconstruct.__module__ = 'numpy.core.multiarray'
+scalar.__module__ = 'numpy.core.multiarray'
+arange.__module__ = 'numpy'
+array.__module__ = 'numpy'
+datetime_data.__module__ = 'numpy'
+empty.__module__ = 'numpy'
+frombuffer.__module__ = 'numpy'
+fromfile.__module__ = 'numpy'
+fromiter.__module__ = 'numpy'
+frompyfunc.__module__ = 'numpy'
+fromstring.__module__ = 'numpy'
+geterrobj.__module__ = 'numpy'
+may_share_memory.__module__ = 'numpy'
+nested_iters.__module__ = 'numpy'
+promote_types.__module__ = 'numpy'
+set_numeric_ops.__module__ = 'numpy'
+seterrobj.__module__ = 'numpy'
+zeros.__module__ = 'numpy'
+# We can't verify dispatcher signatures because NumPy's C functions don't
+# support introspection.
+array_function_from_c_func_and_dispatcher = functools.partial(
+ overrides.array_function_from_dispatcher,
+ module='numpy', docs_from_dispatcher=True, verify=False)
+@array_function_from_c_func_and_dispatcher(_multiarray_umath.empty_like)
+def empty_like(prototype, dtype=None, order=None, subok=None, shape=None):
+ empty_like(prototype, dtype=None, order='K', subok=True, shape=None)
+ Return a new array with the same shape and type as a given array.
+ prototype : array_like
+ The shape and data-type of `prototype` define these same attributes
+ of the returned array.
+ Overrides the data type of the result.
+ order : {'C', 'F', 'A', or 'K'}, optional
+ Overrides the memory layout of the result. 'C' means C-order,
+ 'F' means F-order, 'A' means 'F' if `prototype` is Fortran
+ contiguous, 'C' otherwise. 'K' means match the layout of `prototype`
+ as closely as possible.
+ subok : bool, optional.
+ If True, then the newly created array will use the sub-class
+ type of `prototype`, otherwise it will be a base-class array. Defaults
+ to True.
+ shape : int or sequence of ints, optional.
+ Overrides the shape of the result. If order='K' and the number of
+ dimensions is unchanged, will try to keep order, otherwise,
+ order='C' is implied.
+ Array of uninitialized (arbitrary) data with the same
+ shape and type as `prototype`.
+ This function does *not* initialize the returned array; to do that use
+ `zeros_like` or `ones_like` instead. It may be marginally faster than
+ the functions that do set the array values.
+ >>> a = ([1,2,3], [4,5,6]) # a is array-like
+ >>> np.empty_like(a)
+ array([[-1073741821, -1073741821, 3], # uninitialized
+ [ 0, 0, -1073741821]])
+ >>> a = np.array([[1., 2., 3.],[4.,5.,6.]])
+ array([[ -2.00000715e+000, 1.48219694e-323, -2.00000572e+000], # uninitialized
+ [ 4.38791518e-305, -2.00000715e+000, 4.17269252e-309]])
+ return (prototype,)
+@array_function_from_c_func_and_dispatcher(_multiarray_umath.concatenate)
+def concatenate(arrays, axis=None, out=None, *, dtype=None, casting=None):
+ concatenate((a1, a2, ...), axis=0, out=None, dtype=None, casting="same_kind")
+ Join a sequence of arrays along an existing axis.
+ a1, a2, ... : sequence of array_like
+ The arrays must have the same shape, except in the dimension
+ corresponding to `axis` (the first, by default).
+ The axis along which the arrays will be joined. If axis is None,
+ arrays are flattened before use. Default is 0.
+ If provided, the destination to place the result. The shape must be
+ correct, matching that of what concatenate would have returned if no
+ out argument were specified.
+ If provided, the destination array will have this dtype. Cannot be
+ provided together with `out`.
+ Controls what kind of data casting may occur. Defaults to 'same_kind'.
+ res : ndarray
+ The concatenated array.
+ ma.concatenate : Concatenate function that preserves input masks.
+ array_split : Split an array into multiple sub-arrays of equal or
+ near-equal size.
+ split : Split array into a list of multiple sub-arrays of equal size.
+ hsplit : Split array into multiple sub-arrays horizontally (column wise).
+ vsplit : Split array into multiple sub-arrays vertically (row wise).
+ dsplit : Split array into multiple sub-arrays along the 3rd axis (depth).
+ stack : Stack a sequence of arrays along a new axis.
+ block : Assemble arrays from blocks.
+ hstack : Stack arrays in sequence horizontally (column wise).
+ vstack : Stack arrays in sequence vertically (row wise).
+ dstack : Stack arrays in sequence depth wise (along third dimension).
+ column_stack : Stack 1-D arrays as columns into a 2-D array.
+ When one or more of the arrays to be concatenated is a MaskedArray,
+ this function will return a MaskedArray object instead of an ndarray,
+ but the input masks are *not* preserved. In cases where a MaskedArray
+ is expected as input, use the ma.concatenate function from the masked
+ array module instead.
+ >>> b = np.array([[5, 6]])
+ >>> np.concatenate((a, b), axis=0)
+ >>> np.concatenate((a, b.T), axis=1)
+ array([[1, 2, 5],
+ [3, 4, 6]])
+ >>> np.concatenate((a, b), axis=None)
+ This function will not preserve masking of MaskedArray inputs.
+ >>> a = np.ma.arange(3)
+ >>> a[1] = np.ma.masked
+ >>> b = np.arange(2, 5)
+ masked_array(data=[0, --, 2],
+ mask=[False, True, False],
+ fill_value=999999)
+ array([2, 3, 4])
+ >>> np.concatenate([a, b])
+ masked_array(data=[0, 1, 2, 2, 3, 4],
+ mask=False,
+ >>> np.ma.concatenate([a, b])
+ masked_array(data=[0, --, 2, 2, 3, 4],
+ mask=[False, True, False, False, False, False],
+ # optimize for the typical case where only arrays is provided
+ arrays = list(arrays)
+ arrays.append(out)
+ return arrays
+@array_function_from_c_func_and_dispatcher(_multiarray_umath.inner)
+def inner(a, b):
+ inner(a, b)
+ Inner product of two arrays.
+ Ordinary inner product of vectors for 1-D arrays (without complex
+ conjugation), in higher dimensions a sum product over the last axes.
+ If `a` and `b` are nonscalar, their last dimensions must match.
+ `out.shape = a.shape[:-1] + b.shape[:-1]`
+ If the last dimension of `a` and `b` has different size.
+ tensordot : Sum products over arbitrary axes.
+ dot : Generalised matrix product, using second last dimension of `b`.
+ einsum : Einstein summation convention.
+ For vectors (1-D arrays) it computes the ordinary inner-product::
+ np.inner(a, b) = sum(a[:]*b[:])
+ More generally, if `ndim(a) = r > 0` and `ndim(b) = s > 0`::
+ np.inner(a, b) = np.tensordot(a, b, axes=(-1,-1))
+ or explicitly::
+ np.inner(a, b)[i0,...,ir-1,j0,...,js-1]
+ = sum(a[i0,...,ir-1,:]*b[j0,...,js-1,:])
+ In addition `a` or `b` may be scalars, in which case::
+ np.inner(a,b) = a*b
+ Ordinary inner product for vectors:
+ >>> b = np.array([0,1,0])
+ >>> np.inner(a, b)
+ A multidimensional example:
+ >>> a = np.arange(24).reshape((2,3,4))
+ >>> b = np.arange(4)
+ array([[ 14, 38, 62],
+ [ 86, 110, 134]])
+ An example where `b` is a scalar:
+ >>> np.inner(np.eye(2), 7)
+ array([[7., 0.],
+ [0., 7.]])
+ return (a, b)
+@array_function_from_c_func_and_dispatcher(_multiarray_umath.where)
+def where(condition, x=None, y=None):
+ where(condition, [x, y])
+ Return elements chosen from `x` or `y` depending on `condition`.
+ When only `condition` is provided, this function is a shorthand for
+ ``np.asarray(condition).nonzero()``. Using `nonzero` directly should be
+ preferred, as it behaves correctly for subclasses. The rest of this
+ documentation covers only the case where all three arguments are
+ provided.
+ condition : array_like, bool
+ Where True, yield `x`, otherwise yield `y`.
+ x, y : array_like
+ Values from which to choose. `x`, `y` and `condition` need to be
+ broadcastable to some shape.
+ An array with elements from `x` where `condition` is True, and elements
+ from `y` elsewhere.
+ choose
+ nonzero : The function that is called when x and y are omitted
+ If all the arrays are 1-D, `where` is equivalent to::
+ [xv if c else yv
+ for c, xv, yv in zip(condition, x, y)]
+ >>> np.where(a < 5, a, 10*a)
+ array([ 0, 1, 2, 3, 4, 50, 60, 70, 80, 90])
+ This can be used on multidimensional arrays too:
+ >>> np.where([[True, False], [True, True]],
+ ... [[1, 2], [3, 4]],
+ ... [[9, 8], [7, 6]])
+ array([[1, 8],
+ The shapes of x, y, and the condition are broadcast together:
+ >>> x, y = np.ogrid[:3, :4]
+ >>> np.where(x < y, x, 10 + y) # both x and 10+y are broadcast
+ array([[10, 0, 0, 0],
+ [10, 11, 1, 1],
+ [10, 11, 12, 2]])
+ >>> a = np.array([[0, 1, 2],
+ ... [0, 2, 4],
+ ... [0, 3, 6]])
+ >>> np.where(a < 4, a, -1) # -1 is broadcast
+ array([[ 0, 1, 2],
+ [ 0, 2, -1],
+ [ 0, 3, -1]])
+ return (condition, x, y)
+@array_function_from_c_func_and_dispatcher(_multiarray_umath.lexsort)
+def lexsort(keys, axis=None):
+ lexsort(keys, axis=-1)
+ Perform an indirect stable sort using a sequence of keys.
+ Given multiple sorting keys, which can be interpreted as columns in a
+ spreadsheet, lexsort returns an array of integer indices that describes
+ the sort order by multiple columns. The last key in the sequence is used
+ for the primary sort order, the second-to-last key for the secondary sort
+ order, and so on. The keys argument must be a sequence of objects that
+ can be converted to arrays of the same shape. If a 2D array is provided
+ for the keys argument, its rows are interpreted as the sorting keys and
+ sorting is according to the last row, second last row etc.
+ keys : (k, N) array or tuple containing k (N,)-shaped sequences
+ The `k` different "columns" to be sorted. The last column (or row if
+ `keys` is a 2D array) is the primary sort key.
+ Axis to be indirectly sorted. By default, sort over the last axis.
+ indices : (N,) ndarray of ints
+ Array of indices that sort the keys along the specified axis.
+ ndarray.sort : In-place sort.
+ Sort names: first by surname, then by name.
+ >>> surnames = ('Hertz', 'Galilei', 'Hertz')
+ >>> first_names = ('Heinrich', 'Galileo', 'Gustav')
+ >>> ind = np.lexsort((first_names, surnames))
+ >>> [surnames[i] + ", " + first_names[i] for i in ind]
+ ['Galilei, Galileo', 'Hertz, Gustav', 'Hertz, Heinrich']
+ Sort two columns of numbers:
+ >>> a = [1,5,1,4,3,4,4] # First column
+ >>> b = [9,4,0,4,0,2,1] # Second column
+ >>> ind = np.lexsort((b,a)) # Sort by a, then by b
+ array([2, 0, 4, 6, 5, 3, 1])
+ >>> [(a[i],b[i]) for i in ind]
+ [(1, 0), (1, 9), (3, 0), (4, 1), (4, 2), (4, 4), (5, 4)]
+ Note that sorting is first according to the elements of ``a``.
+ Secondary sorting is according to the elements of ``b``.
+ A normal ``argsort`` would have yielded:
+ >>> [(a[i],b[i]) for i in np.argsort(a)]
+ [(1, 9), (1, 0), (3, 0), (4, 4), (4, 2), (4, 1), (5, 4)]
+ Structured arrays are sorted lexically by ``argsort``:
+ >>> x = np.array([(1,9), (5,4), (1,0), (4,4), (3,0), (4,2), (4,1)],
+ ... dtype=np.dtype([('x', int), ('y', int)]))
+ >>> np.argsort(x) # or np.argsort(x, order=('x', 'y'))
+ if isinstance(keys, tuple):
+ return keys
+ return (keys,)
+@array_function_from_c_func_and_dispatcher(_multiarray_umath.can_cast)
+def can_cast(from_, to, casting=None):
+ can_cast(from_, to, casting='safe')
+ Returns True if cast between data types can occur according to the
+ casting rule. If from is a scalar or array scalar, also returns
+ True if the scalar value can be cast without overflow or truncation
+ to an integer.
+ from_ : dtype, dtype specifier, scalar, or array
+ Data type, scalar, or array to cast from.
+ to : dtype or dtype specifier
+ Data type to cast to.
+ Controls what kind of data casting may occur.
+ out : bool
+ True if cast can occur according to the casting rule.
+ that the string dtype length is long enough to store the maximum
+ dtype, result_type
+ Basic examples
+ >>> np.can_cast(np.int32, np.int64)
+ >>> np.can_cast(np.float64, complex)
+ >>> np.can_cast(complex, float)
+ >>> np.can_cast('i8', 'f8')
+ >>> np.can_cast('i8', 'f4')
+ >>> np.can_cast('i4', 'S4')
+ Casting scalars
+ >>> np.can_cast(100, 'i1')
+ >>> np.can_cast(150, 'i1')
+ >>> np.can_cast(150, 'u1')
+ >>> np.can_cast(3.5e100, np.float32)
+ >>> np.can_cast(1000.0, np.float32)
+ Array scalar checks the value, array does not
+ >>> np.can_cast(np.array(1000.0), np.float32)
+ >>> np.can_cast(np.array([1000.0]), np.float32)
+ Using the casting rules
+ >>> np.can_cast('i8', 'i8', 'no')
+ >>> np.can_cast('<i8', '>i8', 'no')
+ >>> np.can_cast('<i8', '>i8', 'equiv')
+ >>> np.can_cast('<i4', '>i8', 'equiv')
+ >>> np.can_cast('<i4', '>i8', 'safe')
+ >>> np.can_cast('<i8', '>i4', 'safe')
+ >>> np.can_cast('<i8', '>i4', 'same_kind')
+ >>> np.can_cast('<i8', '>u4', 'same_kind')
+ >>> np.can_cast('<i8', '>u4', 'unsafe')
+ return (from_,)
+@array_function_from_c_func_and_dispatcher(_multiarray_umath.min_scalar_type)
+def 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
+ array ``a``, returns the vector's dtype unmodified.
+ Floating point values are not demoted to integers,
+ and complex values are not demoted to floats.
+ a : scalar or array_like
+ The value whose minimal data type is to be found.
+ The minimal data type.
+ result_type, promote_types, dtype, can_cast
+ >>> np.min_scalar_type(10)
+ dtype('uint8')
+ >>> np.min_scalar_type(-260)
+ >>> np.min_scalar_type(3.1)
+ dtype('float16')
+ >>> np.min_scalar_type(1e50)
+ >>> np.min_scalar_type(np.arange(4,dtype='f8'))
+@array_function_from_c_func_and_dispatcher(_multiarray_umath.result_type)
+def result_type(*arrays_and_dtypes):
+ result_type(*arrays_and_dtypes)
+ Returns the type that results from applying the NumPy
+ type promotion rules to the arguments.
+ Type promotion in NumPy works similarly to the rules in languages
+ like C++, with some slight differences. When both scalars and
+ arrays are used, the array's type takes precedence and the actual value
+ of the scalar is taken into account.
+ For example, calculating 3*a, where a is an array of 32-bit floats,
+ intuitively should result in a 32-bit float output. If the 3 is a
+ 32-bit integer, the NumPy rules indicate it can't convert losslessly
+ into a 32-bit float, so a 64-bit float should be the result type.
+ By examining the value of the constant, '3', we see that it fits in
+ an 8-bit integer, which can be cast losslessly into the 32-bit float.
+ arrays_and_dtypes : list of arrays and dtypes
+ The operands of some operation whose result type is needed.
+ The result type.
+ dtype, promote_types, min_scalar_type, can_cast
+ The specific algorithm used is as follows.
+ Categories are determined by first checking which of boolean,
+ integer (int/uint), or floating point (float/complex) the maximum
+ kind of all the arrays and the scalars are.
+ If there are only scalars or the maximum category of the scalars
+ is higher than the maximum category of the arrays,
+ the data types are combined with :func:`promote_types`
+ to produce the return value.
+ Otherwise, `min_scalar_type` is called on each array, and
+ the resulting data types are all combined with :func:`promote_types`
+ The set of int values is not a subset of the uint values for types
+ with the same number of bits, something not reflected in
+ :func:`min_scalar_type`, but handled as a special case in `result_type`.
+ >>> np.result_type(3, np.arange(7, dtype='i1'))
+ dtype('int8')
+ >>> np.result_type('i4', 'c8')
+ >>> np.result_type(3.0, -2)
+ return arrays_and_dtypes
+@array_function_from_c_func_and_dispatcher(_multiarray_umath.dot)
+def dot(a, b, out=None):
+ dot(a, b, out=None)
+ Dot product of two arrays. Specifically,
+ - If both `a` and `b` are 1-D arrays, it is inner product of vectors
+ (without complex conjugation).
+ - If both `a` and `b` are 2-D arrays, it is matrix multiplication,
+ but using :func:`matmul` or ``a @ b`` is preferred.
+ - If either `a` or `b` is 0-D (scalar), it is equivalent to :func:`multiply`
+ and using ``numpy.multiply(a, b)`` or ``a * b`` is preferred.
+ - If `a` is an N-D array and `b` is a 1-D array, it is a sum product over
+ the last axis of `a` and `b`.
+ - If `a` is an N-D array and `b` is an M-D array (where ``M>=2``), it is a
+ sum product over the last axis of `a` and the second-to-last axis of `b`::
+ dot(a, b)[i,j,k,m] = sum(a[i,j,:] * b[k,:,m])
+ First argument.
+ Second argument.
+ Output argument. This must have the exact kind that would be returned
+ if it was not used. In particular, it must have the right type, must be
+ C-contiguous, and its dtype must be the dtype that would be returned
+ for `dot(a,b)`. This is a performance feature. Therefore, if these
+ conditions are not met, an exception is raised, instead of attempting
+ to be flexible.
+ Returns the dot product of `a` and `b`. If `a` and `b` are both
+ scalars or both 1-D arrays then a scalar is returned; otherwise
+ an array is returned.
+ If `out` is given, then it is returned.
+ If the last dimension of `a` is not the same size as
+ the second-to-last dimension of `b`.
+ vdot : Complex-conjugating dot product.
+ matmul : '@' operator as method with out parameter.
+ linalg.multi_dot : Chained dot product.
+ >>> np.dot(3, 4)
+ Neither argument is complex-conjugated:
+ >>> np.dot([2j, 3j], [2j, 3j])
+ (-13+0j)
+ For 2-D arrays it is the matrix product:
+ >>> a = [[1, 0], [0, 1]]
+ >>> b = [[4, 1], [2, 2]]
+ array([[4, 1],
+ >>> a = np.arange(3*4*5*6).reshape((3,4,5,6))
+ >>> b = np.arange(3*4*5*6)[::-1].reshape((5,4,6,3))
+ >>> np.dot(a, b)[2,3,2,1,2,2]
+ 499128
+ >>> sum(a[2,3,2,:] * b[1,2,:,2])
+ return (a, b, out)
+@array_function_from_c_func_and_dispatcher(_multiarray_umath.vdot)
+def vdot(a, b):
+ vdot(a, b)
+ Return the dot product of two vectors.
+ The vdot(`a`, `b`) function handles complex numbers differently than
+ dot(`a`, `b`). If the first argument is complex the complex conjugate
+ of the first argument is used for the calculation of the dot product.
+ Note that `vdot` handles multidimensional arrays differently than `dot`:
+ it does *not* perform a matrix product, but flattens input arguments
+ to 1-D vectors first. Consequently, it should only be used for vectors.
+ If `a` is complex the complex conjugate is taken before calculation
+ of the dot product.
+ Second argument to the dot product.
+ Dot product of `a` and `b`. Can be an int, float, or
+ complex depending on the types of `a` and `b`.
+ dot : Return the dot product without using the complex conjugate of the
+ first argument.
+ >>> a = np.array([1+2j,3+4j])
+ >>> b = np.array([5+6j,7+8j])
+ >>> np.vdot(a, b)
+ (70-8j)
+ >>> np.vdot(b, a)
+ (70+8j)
+ Note that higher-dimensional arrays are flattened!
+ >>> a = np.array([[1, 4], [5, 6]])
+ >>> b = np.array([[4, 1], [2, 2]])
+ >>> 1*4 + 4*1 + 5*2 + 6*2
+@array_function_from_c_func_and_dispatcher(_multiarray_umath.bincount)
+def bincount(x, weights=None, minlength=None):
+ bincount(x, weights=None, minlength=0)
+ Count number of occurrences of each value in array of non-negative ints.
+ The number of bins (of size 1) is one larger than the largest value in
+ `x`. If `minlength` is specified, there will be at least this number
+ of bins in the output array (though it will be longer if necessary,
+ depending on the contents of `x`).
+ Each bin gives the number of occurrences of its index value in `x`.
+ If `weights` is specified the input array is weighted by it, i.e. if a
+ value ``n`` is found at position ``i``, ``out[n] += weight[i]`` instead
+ of ``out[n] += 1``.
+ x : array_like, 1 dimension, nonnegative ints
+ weights : array_like, optional
+ Weights, array of the same shape as `x`.
+ minlength : int, optional
+ A minimum number of bins for the output array.
+ out : ndarray of ints
+ The result of binning the input array.
+ The length of `out` is equal to ``np.amax(x)+1``.
+ If the input is not 1-dimensional, or contains elements with negative
+ values, or if `minlength` is negative.
+ If the type of the input is float or complex.
+ histogram, digitize, unique
+ >>> np.bincount(np.arange(5))
+ array([1, 1, 1, 1, 1])
+ >>> np.bincount(np.array([0, 1, 1, 3, 2, 1, 7]))
+ array([1, 3, 1, 1, 0, 0, 0, 1])
+ >>> x = np.array([0, 1, 1, 3, 2, 1, 7, 23])
+ >>> np.bincount(x).size == np.amax(x)+1
+ The input array needs to be of integer dtype, otherwise a
+ TypeError is raised:
+ >>> np.bincount(np.arange(5, dtype=float))
+ TypeError: Cannot cast array data from dtype('float64') to dtype('int64')
+ according to the rule 'safe'
+ A possible use of ``bincount`` is to perform sums over
+ variable-size chunks of an array, using the ``weights`` keyword.
+ >>> w = np.array([0.3, 0.5, 0.2, 0.7, 1., -0.6]) # weights
+ >>> x = np.array([0, 1, 1, 2, 2, 2])
+ >>> np.bincount(x, weights=w)
+ array([ 0.3, 0.7, 1.1])
+ return (x, weights)
+@array_function_from_c_func_and_dispatcher(_multiarray_umath.ravel_multi_index)
+def ravel_multi_index(multi_index, dims, mode=None, order=None):
+ ravel_multi_index(multi_index, dims, mode='raise', order='C')
+ Converts a tuple of index arrays into an array of flat
+ indices, applying boundary modes to the multi-index.
+ multi_index : tuple of array_like
+ A tuple of integer arrays, one array for each dimension.
+ dims : tuple of ints
+ The shape of array into which the indices from ``multi_index`` apply.
+ Specifies how out-of-bounds indices are handled. Can specify
+ either one mode or a tuple of modes, one mode per index.
+ In 'clip' mode, a negative index which would normally
+ wrap will clip to 0 instead.
+ Determines whether the multi-index should be viewed as
+ indexing in row-major (C-style) or column-major
+ (Fortran-style) order.
+ raveled_indices : ndarray
+ An array of indices into the flattened version of an array
+ of dimensions ``dims``.
+ unravel_index
+ >>> arr = np.array([[3,6,6],[4,5,1]])
+ >>> np.ravel_multi_index(arr, (7,6))
+ array([22, 41, 37])
+ >>> np.ravel_multi_index(arr, (7,6), order='F')
+ array([31, 41, 13])
+ >>> np.ravel_multi_index(arr, (4,6), mode='clip')
+ array([22, 23, 19])
+ >>> np.ravel_multi_index(arr, (4,4), mode=('clip','wrap'))
+ array([12, 13, 13])
+ >>> np.ravel_multi_index((3,1,4,1), (6,7,8,9))
+ 1621
+ return multi_index
+@array_function_from_c_func_and_dispatcher(_multiarray_umath.unravel_index)
+def unravel_index(indices, shape=None, order=None, dims=None):
+ unravel_index(indices, shape, order='C')
+ Converts a flat index or array of flat indices into a tuple
+ of coordinate arrays.
+ An integer array whose elements are indices into the flattened
+ version of an array of dimensions ``shape``. Before version 1.6.0,
+ this function accepted just one index value.
+ The shape of the array to use for unraveling ``indices``.
+ Renamed from ``dims`` to ``shape``.
+ Determines whether the indices should be viewed as indexing in
+ row-major (C-style) or column-major (Fortran-style) order.
+ unraveled_coords : tuple of ndarray
+ Each array in the tuple has the same shape as the ``indices``
+ ravel_multi_index
+ >>> np.unravel_index([22, 41, 37], (7,6))
+ (array([3, 6, 6]), array([4, 5, 1]))
+ >>> np.unravel_index([31, 41, 13], (7,6), order='F')
+ >>> np.unravel_index(1621, (6,7,8,9))
+ (3, 1, 4, 1)
+ if dims is not None:
+ warnings.warn("'shape' argument should be used instead of 'dims'",
+ return (indices,)
+@array_function_from_c_func_and_dispatcher(_multiarray_umath.copyto)
+def copyto(dst, src, casting=None, where=None):
+ copyto(dst, src, casting='same_kind', where=True)
+ Copies values from one array to another, broadcasting as necessary.
+ Raises a TypeError if the `casting` rule is violated, and if
+ `where` is provided, it selects which elements to copy.
+ dst : ndarray
+ The array into which values are copied.
+ src : array_like
+ The array from which values are copied.
+ Controls what kind of data casting may occur when copying.
+ of `dst`, and selects elements to copy from `src` to `dst`
+ wherever it contains the value True.
+ return (dst, src, where)
+@array_function_from_c_func_and_dispatcher(_multiarray_umath.putmask)
+def putmask(a, mask, values):
+ putmask(a, mask, values)
+ Changes elements of an array based on conditional and input values.
+ Sets ``a.flat[n] = values[n]`` for each n where ``mask.flat[n]==True``.
+ If `values` is not the same size as `a` and `mask` then it will repeat.
+ This gives behavior different from ``a[mask] = values``.
+ mask : array_like
+ Boolean mask array. It has to be the same shape as `a`.
+ values : array_like
+ Values to put into `a` where `mask` is True. If `values` is smaller
+ than `a` it will be repeated.
+ place, put, take, copyto
+ >>> np.putmask(x, x>2, x**2)
+ [ 9, 16, 25]])
+ If `values` is smaller than `a` it is repeated:
+ >>> np.putmask(x, x>1, [-33, -44])
+ array([ 0, 1, -33, -44, -33])
+ return (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')
+ Packs the elements of a binary-valued array into bits in a uint8 array.
+ The result is padded to full bytes by inserting zero bits at the end.
+ An array of integers or booleans whose elements should be packed to
+ bits.
+ The dimension over which bit-packing is done.
+ ``None`` implies packing the flattened array.
+ bitorder : {'big', 'little'}, optional
+ The order of the input bits. 'big' will mimic bin(val),
+ ``[0, 0, 0, 0, 0, 0, 1, 1] => 3 = 0b00000011``, 'little' will
+ reverse the order so ``[1, 1, 0, 0, 0, 0, 0, 0] => 3``.
+ Defaults to 'big'.
+ packed : ndarray
+ Array of type uint8 whose elements represent bits corresponding to the
+ logical (0 or nonzero) value of the input elements. The shape of
+ `packed` has the same number of dimensions as the input (unless `axis`
+ is None, in which case the output is 1-D).
+ unpackbits: Unpacks elements of a uint8 array into a binary-valued output
+ >>> a = np.array([[[1,0,1],
+ ... [0,1,0]],
+ ... [[1,1,0],
+ ... [0,0,1]]])
+ >>> b = np.packbits(a, axis=-1)
+ array([[[160],
+ [ 64]],
+ [[192],
+ [ 32]]], dtype=uint8)
+ Note that in binary 160 = 1010 0000, 64 = 0100 0000, 192 = 1100 0000,
+ and 32 = 0010 0000.
+@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')
+ Unpacks elements of a uint8 array into a binary-valued output array.
+ Each element of `a` represents a bit-field that should be unpacked
+ into a binary-valued output array. The shape of the output array is
+ either 1-D (if `axis` is ``None``) or the same shape as the input
+ array with unpacking done along the axis specified.
+ a : ndarray, uint8 type
+ The dimension over which bit-unpacking is done.
+ ``None`` implies unpacking the flattened array.
+ count : int or None, optional
+ The number of elements to unpack along `axis`, provided as a way
+ of undoing the effect of packing a size that is not a multiple
+ of eight. A non-negative number means to only unpack `count`
+ bits. A negative number means to trim off that many bits from
+ the end. ``None`` means to unpack the entire array (the
+ default). Counts larger than the available number of bits will
+ add zero padding to the output. Negative counts must not
+ exceed the available number of bits.
+ The order of the returned bits. 'big' will mimic bin(val),
+ ``3 = 0b00000011 => [0, 0, 0, 0, 0, 0, 1, 1]``, 'little' will reverse
+ the order to ``[1, 1, 0, 0, 0, 0, 0, 0]``.
+ unpacked : ndarray, uint8 type
+ The elements are binary-valued (0 or 1).
+ packbits : Packs the elements of a binary-valued array into bits in
+ a uint8 array.
+ >>> a = np.array([[2], [7], [23]], dtype=np.uint8)
+ array([[ 2],
+ [ 7],
+ [23]], dtype=uint8)
+ >>> b = np.unpackbits(a, axis=1)
+ array([[0, 0, 0, 0, 0, 0, 1, 0],
+ [0, 0, 0, 0, 0, 1, 1, 1],
+ [0, 0, 0, 1, 0, 1, 1, 1]], dtype=uint8)
+ >>> c = np.unpackbits(a, axis=1, count=-3)
+ array([[0, 0, 0, 0, 0],
+ [0, 0, 0, 0, 0],
+ [0, 0, 0, 1, 0]], dtype=uint8)
+ >>> p = np.packbits(b, axis=0)
+ >>> np.unpackbits(p, axis=0)
+ [0, 0, 0, 1, 0, 1, 1, 1],
+ [0, 0, 0, 0, 0, 0, 0, 0],
+ [0, 0, 0, 0, 0, 0, 0, 0]], dtype=uint8)
+ >>> np.array_equal(b, np.unpackbits(p, axis=0, count=b.shape[0]))
+@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)
+ Determine if two arrays share memory.
+ This function can be exponentially slow for some inputs, unless
+ `max_work` is set to a finite number or ``MAY_SHARE_BOUNDS``.
+ If in doubt, use `numpy.may_share_memory` instead.
+ a, b : ndarray
+ Input arrays
+ max_work : int, optional
+ Effort to spend on solving the overlap problem (maximum number
+ of candidate solutions to consider). The following special
+ values are recognized:
+ max_work=MAY_SHARE_EXACT (default)
+ The problem is solved exactly. In this case, the function returns
+ True only if there is an element shared between the arrays. Finding
+ the exact solution may take extremely long in some cases.
+ max_work=MAY_SHARE_BOUNDS
+ Only the memory bounds of a and b are checked.
+ numpy.TooHardError
+ Exceeded max_work.
+ may_share_memory
+ >>> np.shares_memory(x, np.array([5, 6, 7]))
+ >>> np.shares_memory(x[::2], x)
+ >>> np.shares_memory(x[::2], x[1::2])
+ Checking whether two arrays share memory is NP-complete, and
+ runtime may increase exponentially in the number of
+ dimensions. Hence, `max_work` should generally be set to a finite
+ number, as it is possible to construct examples that take
+ extremely long to run:
+ >>> from numpy.lib.stride_tricks import as_strided
+ >>> x = np.zeros([192163377], dtype=np.int8)
+ >>> x1 = as_strided(x, strides=(36674, 61119, 85569), shape=(1049, 1049, 1049))
+ >>> x2 = as_strided(x[64023025:], strides=(12223, 12224, 1), shape=(1049, 1049, 1))
+ >>> np.shares_memory(x1, x2, max_work=1000)
+ numpy.TooHardError: Exceeded max_work
+ Running ``np.shares_memory(x1, x2)`` without `max_work` set takes
+ around 1 minute for this case. It is possible to find problems
+ that take still significantly longer.
+@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)
+ Determine if two arrays might share memory
+ A return of True does not necessarily mean that the two arrays
+ share any element. It just means that they *might*.
+ Only the memory bounds of a and b are checked by default.
+ Effort to spend on solving the overlap problem. See
+ `shares_memory` for details. Default for ``may_share_memory``
+ is to do a bounds check.
+ shares_memory
+ >>> np.may_share_memory(np.array([1,2]), np.array([5,8,9]))
+ >>> x = np.zeros([3, 4])
+ >>> np.may_share_memory(x[:,0], x[:,1])
+@array_function_from_c_func_and_dispatcher(_multiarray_umath.is_busday)
+def is_busday(dates, weekmask=None, holidays=None, busdaycal=None, out=None):
+ is_busday(dates, weekmask='1111100', holidays=None, busdaycal=None, out=None)
+ Calculates which of the given dates are valid days, and which are not.
+ dates : array_like of datetime64[D]
+ The array of dates to process.
+ An array of dates to consider as invalid dates. They may be
+ specified in any order, and NaT (not-a-time) dates are ignored.
+ This list is saved in a normalized form that is suited for
+ fast calculations of valid days.
+ busdaycal : busdaycalendar, optional
+ A `busdaycalendar` object which specifies the valid days. If this
+ parameter is provided, neither weekmask nor holidays may be
+ out : array of bool, optional
+ If provided, this array is filled with the result.
+ out : array of bool
+ An array with the same shape as ``dates``, containing True for
+ each valid day, and False for each invalid day.
+ busdaycalendar: An object that specifies a custom set of valid days.
+ >>> # The weekdays are Friday, Saturday, and Monday
+ ... np.is_busday(['2011-07-01', '2011-07-02', '2011-07-18'],
+ array([False, False, True])
+ return (dates, weekmask, holidays, out)
+@array_function_from_c_func_and_dispatcher(_multiarray_umath.busday_offset)
+def busday_offset(dates, offsets, roll=None, weekmask=None, holidays=None,
+ busdaycal=None, out=None):
+ busday_offset(dates, offsets, roll='raise', weekmask='1111100', holidays=None, busdaycal=None, out=None)
+ First adjusts the date to fall on a valid day according to
+ the ``roll`` rule, then applies offsets to the given dates
+ counted in valid days.
+ offsets : array_like of int
+ The array of offsets, which is broadcast with ``dates``.
+ roll : {'raise', 'nat', 'forward', 'following', 'backward', 'preceding', 'modifiedfollowing', 'modifiedpreceding'}, optional
+ How to treat dates that do not fall on a valid day. The default
+ is 'raise'.
+ * 'raise' means to raise an exception for an invalid day.
+ * 'nat' means to return a NaT (not-a-time) for an invalid day.
+ * 'forward' and 'following' mean to take the first valid day
+ later in time.
+ * 'backward' and 'preceding' mean to take the first valid day
+ earlier in time.
+ * 'modifiedfollowing' means to take the first valid day
+ later in time unless it is across a Month boundary, in which
+ case to take the first valid day earlier in time.
+ * 'modifiedpreceding' means to take the first valid day
+ earlier in time unless it is across a Month boundary, in which
+ case to take the first valid day later in time.
+ out : array of datetime64[D], optional
+ out : array of datetime64[D]
+ An array with a shape from broadcasting ``dates`` and ``offsets``
+ together, containing the dates with offsets applied.
+ >>> # First business day in October 2011 (not accounting for holidays)
+ ... np.busday_offset('2011-10', 0, roll='forward')
+ numpy.datetime64('2011-10-03')
+ >>> # Last business day in February 2012 (not accounting for holidays)
+ ... np.busday_offset('2012-03', -1, roll='forward')
+ numpy.datetime64('2012-02-29')
+ >>> # Third Wednesday in January 2011
+ ... np.busday_offset('2011-01', 2, roll='forward', weekmask='Wed')
+ numpy.datetime64('2011-01-19')
+ >>> # 2012 Mother's Day in Canada and the U.S.
+ ... np.busday_offset('2012-05', 1, roll='forward', weekmask='Sun')
+ numpy.datetime64('2012-05-13')
+ >>> # First business day on or after a date
+ ... np.busday_offset('2011-03-20', 0, roll='forward')
+ numpy.datetime64('2011-03-21')
+ >>> np.busday_offset('2011-03-22', 0, roll='forward')
+ numpy.datetime64('2011-03-22')
+ >>> # First business day after a date
+ ... np.busday_offset('2011-03-20', 1, roll='backward')
+ >>> np.busday_offset('2011-03-22', 1, roll='backward')
+ numpy.datetime64('2011-03-23')
+ return (dates, offsets, weekmask, holidays, out)
+@array_function_from_c_func_and_dispatcher(_multiarray_umath.busday_count)
+def busday_count(begindates, enddates, weekmask=None, holidays=None,
+ busday_count(begindates, enddates, weekmask='1111100', holidays=[], busdaycal=None, out=None)
+ Counts the number of valid days between `begindates` and
+ `enddates`, not including the day of `enddates`.
+ If ``enddates`` specifies a date value that is earlier than the
+ corresponding ``begindates`` date value, the count will be negative.
+ begindates : array_like of datetime64[D]
+ The array of the first dates for counting.
+ enddates : array_like of datetime64[D]
+ The array of the end dates for counting, which are excluded
+ from the count themselves.
+ out : array of int, optional
+ out : array of int
+ An array with a shape from broadcasting ``begindates`` and ``enddates``
+ together, containing the number of valid days between
+ the begin and end dates.
+ >>> # Number of weekdays in January 2011
+ ... np.busday_count('2011-01', '2011-02')
+ 21
+ >>> # Number of weekdays in 2011
+ >>> np.busday_count('2011', '2012')
+ 260
+ >>> # Number of Saturdays in 2011
+ ... np.busday_count('2011', '2012', weekmask='Sat')
+ 53
+ return (begindates, enddates, weekmask, holidays, out)
+@array_function_from_c_func_and_dispatcher(
+ _multiarray_umath.datetime_as_string)
+def datetime_as_string(arr, unit=None, timezone=None, casting=None):
+ datetime_as_string(arr, unit=None, timezone='naive', casting='same_kind')
+ Convert an array of datetimes into an array of strings.
+ arr : array_like of datetime64
+ The array of UTC timestamps to format.
+ One of None, 'auto', or a :ref:`datetime unit <arrays.dtypes.dateunits>`.
+ timezone : {'naive', 'UTC', 'local'} or tzinfo
+ Timezone information to use when displaying the datetime. If 'UTC', end
+ with a Z to indicate UTC time. If 'local', convert to the local timezone
+ first, and suffix with a +-#### timezone offset. If a tzinfo object,
+ then do as with 'local', but use the specified timezone.
+ casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}
+ Casting to allow when changing between datetime units.
+ str_arr : ndarray
+ An array of strings the same shape as `arr`.
+ >>> import pytz
+ >>> d = np.arange('2002-10-27T04:30', 4*60, 60, dtype='M8[m]')
+ >>> d
+ array(['2002-10-27T04:30', '2002-10-27T05:30', '2002-10-27T06:30',
+ '2002-10-27T07:30'], dtype='datetime64[m]')
+ Setting the timezone to UTC shows the same information, but with a Z suffix
+ >>> np.datetime_as_string(d, timezone='UTC')
+ array(['2002-10-27T04:30Z', '2002-10-27T05:30Z', '2002-10-27T06:30Z',
+ '2002-10-27T07:30Z'], dtype='<U35')
+ Note that we picked datetimes that cross a DST boundary. Passing in a
+ ``pytz`` timezone object will print the appropriate offset
+ >>> np.datetime_as_string(d, timezone=pytz.timezone('US/Eastern'))
+ array(['2002-10-27T00:30-0400', '2002-10-27T01:30-0400',
+ '2002-10-27T01:30-0500', '2002-10-27T02:30-0500'], dtype='<U39')
+ Passing in a unit will change the precision
+ >>> np.datetime_as_string(d, unit='h')
+ array(['2002-10-27T04', '2002-10-27T05', '2002-10-27T06', '2002-10-27T07'],
+ dtype='<U32')
+ >>> np.datetime_as_string(d, unit='s')
+ array(['2002-10-27T04:30:00', '2002-10-27T05:30:00', '2002-10-27T06:30:00',
+ '2002-10-27T07:30:00'], dtype='<U38')
+ 'casting' can be used to specify whether precision can be changed
+ >>> np.datetime_as_string(d, unit='h', casting='safe')
+ TypeError: Cannot create a datetime string as units 'h' from a NumPy
+ datetime with units 'm' according to the rule 'safe'
@@ -0,0 +1,2544 @@
+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,
+ concatenate, copyto, dot, dtype, empty,
+ empty_like, flatiter, frombuffer, fromfile, fromiter, fromstring,
+ inner, lexsort, matmul, may_share_memory,
+ min_scalar_type, ndarray, nditer, nested_iters, promote_types,
+ putmask, result_type, set_numeric_ops, shares_memory, vdot, where,
+ zeros, normalize_axis_index)
+from .overrides import set_array_function_like_doc, set_module
+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
+ufunc = type(sin)
+newaxis = None
+ 'newaxis', 'ndarray', 'flatiter', 'nditer', 'nested_iters', 'ufunc',
+ 'arange', 'array', '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',
+ 'result_type', 'isfortran', 'empty_like', 'zeros_like', 'ones_like',
+ 'correlate', 'convolve', 'inner', 'dot', 'outer', 'vdot', 'roll',
+ 'rollaxis', 'moveaxis', 'cross', 'tensordot', 'little_endian',
+ 'fromiter', 'array_equal', 'array_equiv', 'indices', 'fromfunction',
+ 'isclose', 'isscalar', 'binary_repr', 'base_repr', 'ones',
+ 'identity', 'allclose', 'compare_chararrays', 'putmask',
+ 'flatnonzero', 'Inf', 'inf', 'infty', 'Infinity', 'nan', 'NaN',
+ 'False_', 'True_', 'bitwise_not', 'CLIP', 'RAISE', 'WRAP', 'MAXDIMS',
+ 'BUFSIZE', 'ALLOW_THREADS', 'ComplexWarning', 'full', 'full_like',
+ 'matmul', 'shares_memory', 'may_share_memory', 'MAY_SHARE_BOUNDS',
+ 'MAY_SHARE_EXACT', 'TooHardError', 'AxisError']
+class ComplexWarning(RuntimeWarning):
+ The warning raised when casting a complex dtype to a real dtype.
+ As implemented, casting a complex number to a real discards its imaginary
+ part, but this behavior may not be what the user actually wants.
+def _zeros_like_dispatcher(a, dtype=None, order=None, subok=None, shape=None):
+@array_function_dispatch(_zeros_like_dispatcher)
+def zeros_like(a, dtype=None, order='K', subok=True, shape=None):
+ Return an array of zeros with the same shape and type as a given array.
+ The shape and data-type of `a` define these same attributes of
+ the returned array.
+ as possible.
+ type of `a`, otherwise it will be a base-class array. Defaults
+ Array of zeros with the same shape and type as `a`.
+ >>> x = np.arange(6)
+ >>> x = x.reshape((2, 3))
+ >>> np.zeros_like(x)
+ >>> y = np.arange(3, dtype=float)
+ array([0., 1., 2.])
+ >>> np.zeros_like(y)
+ array([0., 0., 0.])
+ res = empty_like(a, dtype=dtype, order=order, subok=subok, shape=shape)
+ # needed instead of a 0 to get same result as zeros for for string dtypes
+ z = zeros(1, dtype=res.dtype)
+ multiarray.copyto(res, z, casting='unsafe')
+def _ones_dispatcher(shape, dtype=None, order=None, *, like=None):
+ return(like,)
+def ones(shape, dtype=None, order='C', *, like=None):
+ Return a new array of given shape and type, filled with ones.
+ shape : int or sequence of ints
+ order : {'C', 'F'}, optional, default: C
+ Array of ones with the given shape, dtype, and order.
+ >>> np.ones(5)
+ array([1., 1., 1., 1., 1.])
+ >>> np.ones((5,), dtype=int)
+ >>> np.ones((2, 1))
+ array([[1.],
+ [1.]])
+ >>> np.ones(s)
+ return _ones_with_like(shape, dtype=dtype, order=order, like=like)
+ a = empty(shape, dtype, order)
+ multiarray.copyto(a, 1, casting='unsafe')
+_ones_with_like = array_function_dispatch(
+ _ones_dispatcher
+)(ones)
+def _ones_like_dispatcher(a, dtype=None, order=None, subok=None, shape=None):
+@array_function_dispatch(_ones_like_dispatcher)
+def ones_like(a, dtype=None, order='K', subok=True, shape=None):
+ Return an array of ones with the same shape and type as a given array.
+ Array of ones with the same shape and type as `a`.
+ >>> np.ones_like(x)
+ array([[1, 1, 1],
+ [1, 1, 1]])
+ >>> np.ones_like(y)
+ array([1., 1., 1.])
+ multiarray.copyto(res, 1, casting='unsafe')
+def _full_dispatcher(shape, fill_value, dtype=None, order=None, *, like=None):
+def full(shape, fill_value, dtype=None, order='C', *, like=None):
+ Return a new array of given shape and type, filled with `fill_value`.
+ fill_value : scalar or array_like
+ Fill value.
+ The desired data-type for the array The default, None, means
+ `np.array(fill_value).dtype`.
+ Whether to store multidimensional data in C- or Fortran-contiguous
+ (row- or column-wise) order in memory.
+ Array of `fill_value` with the given shape, dtype, and order.
+ >>> np.full((2, 2), np.inf)
+ array([[inf, inf],
+ [inf, inf]])
+ >>> np.full((2, 2), 10)
+ array([[10, 10],
+ [10, 10]])
+ >>> np.full((2, 2), [1, 2])
+ [1, 2]])
+ return _full_with_like(shape, fill_value, dtype=dtype, order=order, like=like)
+ fill_value = asarray(fill_value)
+ dtype = fill_value.dtype
+ multiarray.copyto(a, fill_value, casting='unsafe')
+_full_with_like = array_function_dispatch(
+ _full_dispatcher
+)(full)
+def _full_like_dispatcher(a, fill_value, dtype=None, order=None, subok=None, shape=None):
+@array_function_dispatch(_full_like_dispatcher)
+def full_like(a, fill_value, dtype=None, order='K', subok=True, shape=None):
+ Return a full array with the same shape and type as a given array.
+ fill_value : scalar
+ Array of `fill_value` with the same shape and type as `a`.
+ >>> x = np.arange(6, dtype=int)
+ >>> np.full_like(x, 1)
+ array([1, 1, 1, 1, 1, 1])
+ >>> np.full_like(x, 0.1)
+ array([0, 0, 0, 0, 0, 0])
+ >>> np.full_like(x, 0.1, dtype=np.double)
+ array([0.1, 0.1, 0.1, 0.1, 0.1, 0.1])
+ >>> np.full_like(x, np.nan, dtype=np.double)
+ array([nan, nan, nan, nan, nan, nan])
+ >>> y = np.arange(6, dtype=np.double)
+ >>> np.full_like(y, 0.1)
+ multiarray.copyto(res, fill_value, casting='unsafe')
+def _count_nonzero_dispatcher(a, axis=None, *, keepdims=None):
+@array_function_dispatch(_count_nonzero_dispatcher)
+def count_nonzero(a, axis=None, *, keepdims=False):
+ Counts the number of non-zero values in the array ``a``.
+ The word "non-zero" is in reference to the Python 2.x
+ built-in method ``__nonzero__()`` (renamed ``__bool__()``
+ in Python 3.x) of Python objects that tests an object's
+ "truthfulness". For example, any number is considered
+ truthful if it is nonzero, whereas any string is considered
+ truthful if it is not the empty string. Thus, this function
+ (recursively) counts how many elements in ``a`` (and in
+ sub-arrays thereof) have their ``__nonzero__()`` or ``__bool__()``
+ method evaluated to ``True``.
+ The array for which to count non-zeros.
+ axis : int or tuple, optional
+ Axis or tuple of axes along which to count non-zeros.
+ Default is None, meaning that non-zeros will be counted
+ along a flattened version of ``a``.
+ If this is set to True, the axes that are counted are left
+ .. versionadded:: 1.19.0
+ count : int or array of int
+ Number of non-zero values in the array along a given axis.
+ Otherwise, the total number of non-zero values in the array
+ is returned.
+ nonzero : Return the coordinates of all the non-zero values.
+ >>> np.count_nonzero(np.eye(4))
+ >>> a = np.array([[0, 1, 7, 0],
+ ... [3, 0, 2, 19]])
+ >>> np.count_nonzero(a)
+ >>> np.count_nonzero(a, axis=0)
+ array([1, 1, 2, 1])
+ >>> np.count_nonzero(a, axis=1)
+ >>> np.count_nonzero(a, axis=1, keepdims=True)
+ if axis is None and not keepdims:
+ return multiarray.count_nonzero(a)
+ a = asanyarray(a)
+ # TODO: this works around .astype(bool) not working properly (gh-9847)
+ if np.issubdtype(a.dtype, np.character):
+ a_bool = a != a.dtype.type()
+ a_bool = a.astype(np.bool_, copy=False)
+ return a_bool.sum(axis=axis, dtype=np.intp, keepdims=keepdims)
+def isfortran(a):
+ Check if the array is Fortran contiguous but *not* C contiguous.
+ This function is obsolete and, because of changes due to relaxed stride
+ checking, its return value for the same array may differ for versions
+ of NumPy >= 1.10.0 and previous versions. If you only want to check if an
+ array is Fortran contiguous use ``a.flags.f_contiguous`` instead.
+ isfortran : bool
+ Returns True if the array is Fortran contiguous but *not* C contiguous.
+ np.array allows to specify whether the array is written in C-contiguous
+ order (last index varies the fastest), or FORTRAN-contiguous order in
+ memory (first index varies the fastest).
+ >>> a = np.array([[1, 2, 3], [4, 5, 6]], order='C')
+ >>> np.isfortran(a)
+ >>> b = np.array([[1, 2, 3], [4, 5, 6]], order='F')
+ >>> np.isfortran(b)
+ The transpose of a C-ordered array is a FORTRAN-ordered array.
+ C-ordered arrays evaluate as False even if they are also FORTRAN-ordered.
+ >>> np.isfortran(np.array([1, 2], order='F'))
+ return a.flags.fnc
+def _argwhere_dispatcher(a):
+@array_function_dispatch(_argwhere_dispatcher)
+def argwhere(a):
+ Find the indices of array elements that are non-zero, grouped by element.
+ index_array : (N, a.ndim) ndarray
+ Indices of elements that are non-zero. Indices are grouped by element.
+ This array will have shape ``(N, a.ndim)`` where ``N`` is the number of
+ non-zero items.
+ where, nonzero
+ ``np.argwhere(a)`` is almost the same as ``np.transpose(np.nonzero(a))``,
+ but produces a result of the correct shape for a 0D array.
+ The output of ``argwhere`` is not suitable for indexing arrays.
+ For this purpose use ``nonzero(a)`` instead.
+ >>> np.argwhere(x>1)
+ [1, 0],
+ # nonzero does not behave well on 0d, so promote to 1d
+ if np.ndim(a) == 0:
+ a = shape_base.atleast_1d(a)
+ # then remove the added dimension
+ return argwhere(a)[:,:0]
+ return transpose(nonzero(a))
+def _flatnonzero_dispatcher(a):
+@array_function_dispatch(_flatnonzero_dispatcher)
+def flatnonzero(a):
+ Return indices that are non-zero in the flattened version of a.
+ This is equivalent to np.nonzero(np.ravel(a))[0].
+ Output array, containing the indices of the elements of `a.ravel()`
+ that are non-zero.
+ nonzero : Return the indices of the non-zero elements of the input array.
+ ravel : Return a 1-D array containing the elements of the input array.
+ >>> x = np.arange(-2, 3)
+ array([-2, -1, 0, 1, 2])
+ >>> np.flatnonzero(x)
+ array([0, 1, 3, 4])
+ Use the indices of the non-zero elements as an index array to extract
+ these elements:
+ >>> x.ravel()[np.flatnonzero(x)]
+ array([-2, -1, 1, 2])
+ 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)
+@array_function_dispatch(_correlate_dispatcher)
+def correlate(a, v, mode='valid'):
+ Cross-correlation of two 1-dimensional sequences.
+ This function computes the correlation as generally defined in signal
+ processing texts::
+ c_{av}[k] = sum_n a[n+k] * conj(v[n])
+ with a and v sequences being zero-padded where necessary and conj being
+ the conjugate.
+ a, v : array_like
+ Input sequences.
+ mode : {'valid', 'same', 'full'}, optional
+ Refer to the `convolve` docstring. Note that the default
+ is 'valid', unlike `convolve`, which uses 'full'.
+ old_behavior : bool
+ `old_behavior` was removed in NumPy 1.10. If you need the old
+ behavior, use `multiarray.correlate`.
+ Discrete cross-correlation of `a` and `v`.
+ convolve : Discrete, linear convolution of two one-dimensional sequences.
+ multiarray.correlate : Old, no conjugate, version of correlate.
+ The definition of correlation above is not unique and sometimes correlation
+ may be defined differently. Another common definition is::
+ c'_{av}[k] = sum_n a[n] conj(v[n+k])
+ which is related to ``c_{av}[k]`` by ``c'_{av}[k] = c_{av}[-k]``.
+ >>> np.correlate([1, 2, 3], [0, 1, 0.5])
+ array([3.5])
+ >>> np.correlate([1, 2, 3], [0, 1, 0.5], "same")
+ array([2. , 3.5, 3. ])
+ >>> np.correlate([1, 2, 3], [0, 1, 0.5], "full")
+ array([0.5, 2. , 3.5, 3. , 0. ])
+ Using complex sequences:
+ >>> np.correlate([1+1j, 2, 3-1j], [0, 1, 0.5j], 'full')
+ array([ 0.5-0.5j, 1.0+0.j , 1.5-1.5j, 3.0-1.j , 0.0+0.j ])
+ Note that you get the time reversed, complex conjugated result
+ when the two input sequences change places, i.e.,
+ ``c_{va}[k] = c^{*}_{av}[-k]``:
+ >>> np.correlate([0, 1, 0.5j], [1+1j, 2, 3-1j], 'full')
+ 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)
+def _convolve_dispatcher(a, v, mode=None):
+@array_function_dispatch(_convolve_dispatcher)
+def convolve(a, v, mode='full'):
+ Returns the discrete, linear convolution of two one-dimensional sequences.
+ The convolution operator is often seen in signal processing, where it
+ models the effect of a linear time-invariant system on a signal [1]_. In
+ probability theory, the sum of two independent random variables is
+ distributed according to the convolution of their individual
+ distributions.
+ If `v` is longer than `a`, the arrays are swapped before computation.
+ a : (N,) array_like
+ First one-dimensional input array.
+ v : (M,) array_like
+ Second one-dimensional input array.
+ mode : {'full', 'valid', 'same'}, optional
+ 'full':
+ By default, mode is 'full'. This returns the convolution
+ at each point of overlap, with an output shape of (N+M-1,). At
+ the end-points of the convolution, the signals do not overlap
+ completely, and boundary effects may be seen.
+ 'same':
+ Mode 'same' returns output of length ``max(M, N)``. Boundary
+ effects are still visible.
+ 'valid':
+ Mode 'valid' returns output of length
+ ``max(M, N) - min(M, N) + 1``. The convolution product is only given
+ for points where the signals overlap completely. Values outside
+ the signal boundary have no effect.
+ Discrete, linear convolution of `a` and `v`.
+ scipy.signal.fftconvolve : Convolve two arrays using the Fast Fourier
+ Transform.
+ scipy.linalg.toeplitz : Used to construct the convolution operator.
+ polymul : Polynomial multiplication. Same output as convolve, but also
+ accepts poly1d objects as input.
+ The discrete convolution operation is defined as
+ .. math:: (a * v)[n] = \\sum_{m = -\\infty}^{\\infty} a[m] v[n - m]
+ It can be shown that a convolution :math:`x(t) * y(t)` in time/space
+ is equivalent to the multiplication :math:`X(f) Y(f)` in the Fourier
+ domain, after appropriate padding (padding is necessary to prevent
+ circular convolution). Since multiplication is more efficient (faster)
+ than convolution, the function `scipy.signal.fftconvolve` exploits the
+ FFT to calculate the convolution of large data-sets.
+ .. [1] Wikipedia, "Convolution",
+ https://en.wikipedia.org/wiki/Convolution
+ Note how the convolution operator flips the second array
+ before "sliding" the two across one another:
+ >>> np.convolve([1, 2, 3], [0, 1, 0.5])
+ array([0. , 1. , 2.5, 4. , 1.5])
+ Only return the middle values of the convolution.
+ Contains boundary effects, where zeros are taken
+ into account:
+ >>> np.convolve([1,2,3],[0,1,0.5], 'same')
+ array([1. , 2.5, 4. ])
+ The two arrays are of the same length, so there
+ is only one position where they completely overlap:
+ >>> np.convolve([1,2,3],[0,1,0.5], 'valid')
+ array([2.5])
+ a, v = array(a, copy=False, ndmin=1), array(v, copy=False, ndmin=1)
+ if (len(v) > len(a)):
+ a, v = v, a
+ if len(a) == 0:
+ raise ValueError('a cannot be empty')
+ if len(v) == 0:
+ raise ValueError('v cannot be empty')
+ return multiarray.correlate(a, v[::-1], mode)
+def _outer_dispatcher(a, b, out=None):
+@array_function_dispatch(_outer_dispatcher)
+def outer(a, b, out=None):
+ Compute the outer product of two vectors.
+ Given two vectors, ``a = [a0, a1, ..., aM]`` and
+ ``b = [b0, b1, ..., bN]``,
+ the outer product [1]_ is::
+ [[a0*b0 a0*b1 ... a0*bN ]
+ [a1*b0 .
+ [ ... .
+ [aM*b0 aM*bN ]]
+ a : (M,) array_like
+ First input vector. Input is flattened if
+ not already 1-dimensional.
+ b : (N,) array_like
+ Second input vector. Input is flattened if
+ out : (M, N) ndarray, optional
+ A location where the result is stored
+ out : (M, N) ndarray
+ ``out[i, j] = a[i] * b[j]``
+ inner
+ einsum : ``einsum('i,j->ij', a.ravel(), b.ravel())`` is the equivalent.
+ ufunc.outer : A generalization to dimensions other than 1D and other
+ operations. ``np.multiply.outer(a.ravel(), b.ravel())``
+ is the equivalent.
+ tensordot : ``np.tensordot(a.ravel(), b.ravel(), axes=((), ()))``
+ .. [1] : G. H. Golub and C. F. Van Loan, *Matrix Computations*, 3rd
+ ed., Baltimore, MD, Johns Hopkins University Press, 1996,
+ pg. 8.
+ Make a (*very* coarse) grid for computing a Mandelbrot set:
+ >>> rl = np.outer(np.ones((5,)), np.linspace(-2, 2, 5))
+ >>> rl
+ array([[-2., -1., 0., 1., 2.],
+ [-2., -1., 0., 1., 2.],
+ [-2., -1., 0., 1., 2.]])
+ >>> im = np.outer(1j*np.linspace(2, -2, 5), np.ones((5,)))
+ >>> im
+ array([[0.+2.j, 0.+2.j, 0.+2.j, 0.+2.j, 0.+2.j],
+ [0.+1.j, 0.+1.j, 0.+1.j, 0.+1.j, 0.+1.j],
+ [0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
+ [0.-1.j, 0.-1.j, 0.-1.j, 0.-1.j, 0.-1.j],
+ [0.-2.j, 0.-2.j, 0.-2.j, 0.-2.j, 0.-2.j]])
+ >>> grid = rl + im
+ >>> grid
+ array([[-2.+2.j, -1.+2.j, 0.+2.j, 1.+2.j, 2.+2.j],
+ [-2.+1.j, -1.+1.j, 0.+1.j, 1.+1.j, 2.+1.j],
+ [-2.+0.j, -1.+0.j, 0.+0.j, 1.+0.j, 2.+0.j],
+ [-2.-1.j, -1.-1.j, 0.-1.j, 1.-1.j, 2.-1.j],
+ [-2.-2.j, -1.-2.j, 0.-2.j, 1.-2.j, 2.-2.j]])
+ An example using a "vector" of letters:
+ >>> x = np.array(['a', 'b', 'c'], dtype=object)
+ >>> np.outer(x, [1, 2, 3])
+ array([['a', 'aa', 'aaa'],
+ ['b', 'bb', 'bbb'],
+ ['c', 'cc', 'ccc']], dtype=object)
+ a = asarray(a)
+ b = asarray(b)
+ return multiply(a.ravel()[:, newaxis], b.ravel()[newaxis, :], out)
+def _tensordot_dispatcher(a, b, axes=None):
+@array_function_dispatch(_tensordot_dispatcher)
+def tensordot(a, b, axes=2):
+ Compute tensor dot product along specified axes.
+ Given two tensors, `a` and `b`, and an array_like object containing
+ two array_like objects, ``(a_axes, b_axes)``, sum the products of
+ `a`'s and `b`'s elements (components) over the axes specified by
+ ``a_axes`` and ``b_axes``. The third argument can be a single non-negative
+ integer_like scalar, ``N``; if it is such, then the last ``N`` dimensions
+ of `a` and the first ``N`` dimensions of `b` are summed over.
+ Tensors to "dot".
+ axes : int or (2,) array_like
+ * integer_like
+ If an int N, sum over the last N axes of `a` and the first N axes
+ of `b` in order. The sizes of the corresponding axes must match.
+ * (2,) array_like
+ Or, a list of axes to be summed over, first sequence applying to `a`,
+ second to `b`. Both elements array_like must be of the same length.
+ The tensor dot product of the input.
+ dot, einsum
+ Three common use cases are:
+ * ``axes = 0`` : tensor product :math:`a\\otimes b`
+ * ``axes = 1`` : tensor dot product :math:`a\\cdot b`
+ * ``axes = 2`` : (default) tensor double contraction :math:`a:b`
+ When `axes` is integer_like, the sequence for evaluation will be: first
+ the -Nth axis in `a` and 0th axis in `b`, and the -1th axis in `a` and
+ Nth axis in `b` last.
+ When there is more than one axis to sum over - and they are not the last
+ (first) axes of `a` (`b`) - the argument `axes` should consist of
+ two sequences of the same length, with the first axis to sum over given
+ first in both sequences, the second axis second, and so forth.
+ The shape of the result consists of the non-contracted axes of the
+ first tensor, followed by the non-contracted axes of the second.
+ A "traditional" example:
+ >>> c = np.tensordot(a,b, axes=([1,0],[0,1]))
+ >>> c.shape
+ (5, 2)
+ >>> # A slower but equivalent way of computing the same...
+ >>> d = np.zeros((5,2))
+ >>> for i in range(5):
+ ... for j in range(2):
+ ... for k in range(3):
+ ... for n in range(4):
+ ... d[i,j] += a[k,n,i] * b[n,k,j]
+ >>> c == d
+ array([[ True, True],
+ [ True, True],
+ [ True, True]])
+ An extended example taking advantage of the overloading of + and \\*:
+ >>> a = np.array(range(1, 9))
+ >>> a.shape = (2, 2, 2)
+ >>> A = np.array(('a', 'b', 'c', 'd'), dtype=object)
+ >>> A.shape = (2, 2)
+ >>> a; A
+ array([[[1, 2],
+ [3, 4]],
+ [[5, 6],
+ [7, 8]]])
+ array([['a', 'b'],
+ ['c', 'd']], dtype=object)
+ >>> np.tensordot(a, A) # third argument default is 2 for double-contraction
+ array(['abbcccdddd', 'aaaaabbbbbbcccccccdddddddd'], dtype=object)
+ >>> np.tensordot(a, A, 1)
+ array([[['acc', 'bdd'],
+ ['aaacccc', 'bbbdddd']],
+ [['aaaaacccccc', 'bbbbbdddddd'],
+ ['aaaaaaacccccccc', 'bbbbbbbdddddddd']]], dtype=object)
+ >>> np.tensordot(a, A, 0) # tensor product (result too long to incl.)
+ array([[[[['a', 'b'],
+ ['c', 'd']],
+ >>> np.tensordot(a, A, (0, 1))
+ array([[['abbbbb', 'cddddd'],
+ ['aabbbbbb', 'ccdddddd']],
+ [['aaabbbbbbb', 'cccddddddd'],
+ ['aaaabbbbbbbb', 'ccccdddddddd']]], dtype=object)
+ >>> np.tensordot(a, A, (2, 1))
+ array([[['abb', 'cdd'],
+ ['aaabbbb', 'cccdddd']],
+ [['aaaaabbbbbb', 'cccccdddddd'],
+ ['aaaaaaabbbbbbbb', 'cccccccdddddddd']]], dtype=object)
+ >>> np.tensordot(a, A, ((0, 1), (0, 1)))
+ array(['abbbcccccddddddd', 'aabbbbccccccdddddddd'], dtype=object)
+ >>> np.tensordot(a, A, ((2, 1), (1, 0)))
+ array(['acccbbdddd', 'aaaaacccccccbbbbbbdddddddd'], dtype=object)
+ iter(axes)
+ axes_a = list(range(-axes, 0))
+ axes_b = list(range(0, axes))
+ axes_a, axes_b = axes
+ na = len(axes_a)
+ axes_a = list(axes_a)
+ axes_a = [axes_a]
+ na = 1
+ nb = len(axes_b)
+ axes_b = list(axes_b)
+ axes_b = [axes_b]
+ nb = 1
+ a, b = asarray(a), asarray(b)
+ as_ = a.shape
+ nda = a.ndim
+ bs = b.shape
+ ndb = b.ndim
+ equal = True
+ if na != nb:
+ equal = False
+ for k in range(na):
+ if as_[axes_a[k]] != bs[axes_b[k]]:
+ if axes_a[k] < 0:
+ axes_a[k] += nda
+ if axes_b[k] < 0:
+ axes_b[k] += ndb
+ if not equal:
+ raise ValueError("shape-mismatch for sum")
+ # Move the axes to sum over to the end of "a"
+ # and to the front of "b"
+ notin = [k for k in range(nda) if k not in axes_a]
+ newaxes_a = notin + axes_a
+ N2 = 1
+ for axis in axes_a:
+ N2 *= as_[axis]
+ newshape_a = (int(multiply.reduce([as_[ax] for ax in notin])), N2)
+ olda = [as_[axis] for axis in notin]
+ notin = [k for k in range(ndb) if k not in axes_b]
+ newaxes_b = axes_b + notin
+ for axis in axes_b:
+ N2 *= bs[axis]
+ newshape_b = (N2, int(multiply.reduce([bs[ax] for ax in notin])))
+ oldb = [bs[axis] for axis in notin]
+ at = a.transpose(newaxes_a).reshape(newshape_a)
+ bt = b.transpose(newaxes_b).reshape(newshape_b)
+ res = dot(at, bt)
+ return res.reshape(olda + oldb)
+def _roll_dispatcher(a, shift, axis=None):
+@array_function_dispatch(_roll_dispatcher)
+def roll(a, shift, axis=None):
+ Roll array elements along a given axis.
+ Elements that roll beyond the last position are re-introduced at
+ the first.
+ shift : int or tuple of ints
+ The number of places by which elements are shifted. If a tuple,
+ then `axis` must be a tuple of the same size, and each of the
+ given axes is shifted by the corresponding number. If an int
+ while `axis` is a tuple of ints, then the same value is used for
+ all given axes.
+ axis : int or tuple of ints, optional
+ Axis or axes along which elements are shifted. By default, the
+ array is flattened before shifting, after which the original
+ shape is restored.
+ Output array, with the same shape as `a`.
+ rollaxis : Roll the specified axis backwards, until it lies in a
+ given position.
+ Supports rolling over multiple dimensions simultaneously.
+ >>> np.roll(x, 2)
+ array([8, 9, 0, 1, 2, 3, 4, 5, 6, 7])
+ >>> np.roll(x, -2)
+ array([2, 3, 4, 5, 6, 7, 8, 9, 0, 1])
+ >>> x2 = np.reshape(x, (2,5))
+ >>> x2
+ [5, 6, 7, 8, 9]])
+ >>> np.roll(x2, 1)
+ array([[9, 0, 1, 2, 3],
+ [4, 5, 6, 7, 8]])
+ >>> np.roll(x2, -1)
+ array([[1, 2, 3, 4, 5],
+ [6, 7, 8, 9, 0]])
+ >>> np.roll(x2, 1, axis=0)
+ array([[5, 6, 7, 8, 9],
+ [0, 1, 2, 3, 4]])
+ >>> np.roll(x2, -1, axis=0)
+ >>> np.roll(x2, 1, axis=1)
+ array([[4, 0, 1, 2, 3],
+ [9, 5, 6, 7, 8]])
+ >>> np.roll(x2, -1, axis=1)
+ array([[1, 2, 3, 4, 0],
+ [6, 7, 8, 9, 5]])
+ return roll(a.ravel(), shift, 0).reshape(a.shape)
+ axis = normalize_axis_tuple(axis, a.ndim, allow_duplicate=True)
+ broadcasted = broadcast(shift, axis)
+ if broadcasted.ndim > 1:
+ "'shift' and 'axis' should be scalars or 1D sequences")
+ shifts = {ax: 0 for ax in range(a.ndim)}
+ for sh, ax in broadcasted:
+ shifts[ax] += sh
+ rolls = [((slice(None), slice(None)),)] * a.ndim
+ for ax, offset in shifts.items():
+ offset %= a.shape[ax] or 1 # If `a` is empty, nothing matters.
+ if offset:
+ # (original, result), (original, result)
+ rolls[ax] = ((slice(None, -offset), slice(offset, None)),
+ (slice(-offset, None), slice(None, offset)))
+ result = empty_like(a)
+ for indices in itertools.product(*rolls):
+ arr_index, res_index = zip(*indices)
+ result[res_index] = a[arr_index]
+def _rollaxis_dispatcher(a, axis, start=None):
+@array_function_dispatch(_rollaxis_dispatcher)
+def rollaxis(a, axis, start=0):
+ Roll the specified axis backwards, until it lies in a given position.
+ This function continues to be supported for backward compatibility, but you
+ should prefer `moveaxis`. The `moveaxis` function was added in NumPy
+ 1.11.
+ The axis to be rolled. The positions of the other axes do not
+ change relative to one another.
+ start : int, optional
+ When ``start <= axis``, the axis is rolled back until it lies in
+ this position. When ``start > axis``, the axis is rolled until it
+ lies before this position. The default, 0, results in a "complete"
+ roll. The following table describes how negative values of ``start``
+ are interpreted:
+ .. table::
+ :align: left
+ +-------------------+----------------------+
+ | ``start`` | Normalized ``start`` |
+ +===================+======================+
+ | ``-(arr.ndim+1)`` | raise ``AxisError`` |
+ | ``-arr.ndim`` | 0 |
+ | |vdots| | |vdots| |
+ | ``-1`` | ``arr.ndim-1`` |
+ | ``0`` | ``0`` |
+ | ``arr.ndim`` | ``arr.ndim`` |
+ | ``arr.ndim + 1`` | raise ``AxisError`` |
+ .. |vdots| unicode:: U+22EE .. Vertical Ellipsis
+ For NumPy >= 1.10.0 a view of `a` is always returned. For earlier
+ NumPy versions a view of `a` is returned only if the order of the
+ moveaxis : Move array axes to new positions.
+ roll : Roll the elements of an array by a number of positions along a
+ given axis.
+ >>> a = np.ones((3,4,5,6))
+ >>> np.rollaxis(a, 3, 1).shape
+ (3, 6, 4, 5)
+ >>> np.rollaxis(a, 2).shape
+ (5, 3, 4, 6)
+ >>> np.rollaxis(a, 1, 4).shape
+ (3, 5, 6, 4)
+ n = a.ndim
+ axis = normalize_axis_index(axis, n)
+ if start < 0:
+ start += n
+ msg = "'%s' arg requires %d <= %s < %d, but %d was passed in"
+ if not (0 <= start < n + 1):
+ raise AxisError(msg % ('start', -n, 'start', n + 1, start))
+ if axis < start:
+ # it's been removed
+ start -= 1
+ if axis == start:
+ return a[...]
+ axes = list(range(0, n))
+ axes.remove(axis)
+ axes.insert(start, axis)
+ return a.transpose(axes)
+def normalize_axis_tuple(axis, ndim, argname=None, allow_duplicate=False):
+ Normalizes an axis argument into a tuple of non-negative integer axes.
+ This handles shorthands such as ``1`` and converts them to ``(1,)``,
+ as well as performing the handling of negative indices covered by
+ `normalize_axis_index`.
+ By default, this forbids axes from being specified multiple times.
+ Used internally by multi-axis-checking logic.
+ axis : int, iterable of int
+ The un-normalized index or indices of the axis.
+ against.
+ argname : str, optional
+ A prefix to put before the error message, typically the name of the
+ argument.
+ allow_duplicate : bool, optional
+ If False, the default, disallow an axis from being specified twice.
+ normalized_axes : tuple of int
+ If any axis provided is out of range
+ If an axis is repeated
+ normalize_axis_index : normalizing a single scalar axis
+ # Optimization to speed-up the most common cases.
+ if type(axis) not in (tuple, list):
+ axis = [operator.index(axis)]
+ # Going via an iterator directly is slower than via list comprehension.
+ axis = tuple([normalize_axis_index(ax, ndim, argname) for ax in axis])
+ if not allow_duplicate and len(set(axis)) != len(axis):
+ if argname:
+ raise ValueError('repeated axis in `{}` argument'.format(argname))
+ raise ValueError('repeated axis')
+ return axis
+def _moveaxis_dispatcher(a, source, destination):
+@array_function_dispatch(_moveaxis_dispatcher)
+def moveaxis(a, source, destination):
+ Move axes of an array to new positions.
+ Other axes remain in their original order.
+ .. versionadded:: 1.11.0
+ a : np.ndarray
+ The array whose axes should be reordered.
+ source : int or sequence of int
+ Original positions of the axes to move. These must be unique.
+ destination : int or sequence of int
+ Destination positions for each of the original axes. These must also be
+ unique.
+ result : np.ndarray
+ Array with moved axes. This array is a view of the input array.
+ transpose: Permute the dimensions of an array.
+ swapaxes: Interchange two axes of an array.
+ >>> x = np.zeros((3, 4, 5))
+ >>> np.moveaxis(x, 0, -1).shape
+ (4, 5, 3)
+ >>> np.moveaxis(x, -1, 0).shape
+ (5, 3, 4)
+ These all achieve the same result:
+ (5, 4, 3)
+ >>> np.swapaxes(x, 0, -1).shape
+ >>> np.moveaxis(x, [0, 1], [-1, -2]).shape
+ >>> np.moveaxis(x, [0, 1, 2], [-1, -2, -3]).shape
+ # allow duck-array types if they define transpose
+ transpose = a.transpose
+ source = normalize_axis_tuple(source, a.ndim, 'source')
+ destination = normalize_axis_tuple(destination, a.ndim, 'destination')
+ if len(source) != len(destination):
+ raise ValueError('`source` and `destination` arguments must have '
+ 'the same number of elements')
+ order = [n for n in range(a.ndim) if n not in source]
+ for dest, src in sorted(zip(destination, source)):
+ order.insert(dest, src)
+ result = transpose(order)
+# 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):
+@array_function_dispatch(_cross_dispatcher)
+def cross(a, b, axisa=-1, axisb=-1, axisc=-1, axis=None):
+ Return the cross product of two (arrays of) vectors.
+ The cross product of `a` and `b` in :math:`R^3` is a vector perpendicular
+ to both `a` and `b`. If `a` and `b` are arrays of vectors, the vectors
+ are defined by the last axis of `a` and `b` by default, and these axes
+ can have dimensions 2 or 3. Where the dimension of either `a` or `b` is
+ 2, the third component of the input vector is assumed to be zero and the
+ cross product calculated accordingly. In cases where both input vectors
+ have dimension 2, the z-component of the cross product is returned.
+ Components of the first vector(s).
+ Components of the second vector(s).
+ axisa : int, optional
+ Axis of `a` that defines the vector(s). By default, the last axis.
+ axisb : int, optional
+ Axis of `b` that defines the vector(s). By default, the last axis.
+ axisc : int, optional
+ Axis of `c` containing the cross product vector(s). Ignored if
+ both input vectors have dimension 2, as the return is scalar.
+ By default, the last axis.
+ If defined, the axis of `a`, `b` and `c` that defines the vector(s)
+ and cross product(s). Overrides `axisa`, `axisb` and `axisc`.
+ c : ndarray
+ Vector cross product(s).
+ When the dimension of the vector(s) in `a` and/or `b` does not
+ equal 2 or 3.
+ inner : Inner product
+ outer : Outer product.
+ ix_ : Construct index arrays.
+ Supports full broadcasting of the inputs.
+ Vector cross-product.
+ >>> x = [1, 2, 3]
+ >>> y = [4, 5, 6]
+ >>> np.cross(x, y)
+ array([-3, 6, -3])
+ One vector with dimension 2.
+ >>> x = [1, 2]
+ array([12, -6, -3])
+ Equivalently:
+ >>> x = [1, 2, 0]
+ Both vectors with dimension 2.
+ >>> x = [1,2]
+ >>> y = [4,5]
+ array(-3)
+ Multiple vector cross-products. Note that the direction of the cross
+ product vector is defined by the `right-hand rule`.
+ >>> x = np.array([[1,2,3], [4,5,6]])
+ >>> y = np.array([[4,5,6], [1,2,3]])
+ array([[-3, 6, -3],
+ [ 3, -6, 3]])
+ The orientation of `c` can be changed using the `axisc` keyword.
+ >>> np.cross(x, y, axisc=0)
+ array([[-3, 3],
+ [ 6, -6],
+ [-3, 3]])
+ Change the vector definition of `x` and `y` using `axisa` and `axisb`.
+ >>> x = np.array([[1,2,3], [4,5,6], [7, 8, 9]])
+ >>> y = np.array([[7, 8, 9], [4,5,6], [1,2,3]])
+ array([[ -6, 12, -6],
+ [ 0, 0, 0],
+ [ 6, -12, 6]])
+ >>> np.cross(x, y, axisa=0, axisb=0)
+ array([[-24, 48, -24],
+ [-30, 60, -30],
+ [-36, 72, -36]])
+ if axis is not None:
+ axisa, axisb, axisc = (axis,) * 3
+ # Check axisa and axisb are within bounds
+ axisa = normalize_axis_index(axisa, a.ndim, msg_prefix='axisa')
+ axisb = normalize_axis_index(axisb, b.ndim, msg_prefix='axisb')
+ # Move working axis to the end of the shape
+ a = moveaxis(a, axisa, -1)
+ b = moveaxis(b, axisb, -1)
+ msg = ("incompatible dimensions for cross product\n"
+ "(dimension must be 2 or 3)")
+ if a.shape[-1] not in (2, 3) or b.shape[-1] not in (2, 3):
+ raise ValueError(msg)
+ # Create the output array
+ shape = broadcast(a[..., 0], b[..., 0]).shape
+ if a.shape[-1] == 3 or b.shape[-1] == 3:
+ shape += (3,)
+ # Check axisc is within bounds
+ axisc = normalize_axis_index(axisc, len(shape), msg_prefix='axisc')
+ dtype = promote_types(a.dtype, b.dtype)
+ cp = empty(shape, dtype)
+ # create local aliases for readability
+ a0 = a[..., 0]
+ a1 = a[..., 1]
+ if a.shape[-1] == 3:
+ a2 = a[..., 2]
+ b0 = b[..., 0]
+ b1 = b[..., 1]
+ if b.shape[-1] == 3:
+ b2 = b[..., 2]
+ if cp.ndim != 0 and cp.shape[-1] == 3:
+ cp0 = cp[..., 0]
+ cp1 = cp[..., 1]
+ cp2 = cp[..., 2]
+ if a.shape[-1] == 2:
+ if b.shape[-1] == 2:
+ # a0 * b1 - a1 * b0
+ multiply(a0, b1, out=cp)
+ cp -= a1 * b0
+ return cp
+ assert b.shape[-1] == 3
+ # cp0 = a1 * b2 - 0 (a2 = 0)
+ # cp1 = 0 - a0 * b2 (a2 = 0)
+ # cp2 = a0 * b1 - a1 * b0
+ multiply(a1, b2, out=cp0)
+ multiply(a0, b2, out=cp1)
+ negative(cp1, out=cp1)
+ multiply(a0, b1, out=cp2)
+ cp2 -= a1 * b0
+ assert a.shape[-1] == 3
+ # cp0 = a1 * b2 - a2 * b1
+ # cp1 = a2 * b0 - a0 * b2
+ tmp = array(a2 * b1)
+ cp0 -= tmp
+ multiply(a2, b0, out=cp1)
+ multiply(a0, b2, out=tmp)
+ cp1 -= tmp
+ multiply(a1, b0, out=tmp)
+ cp2 -= tmp
+ assert b.shape[-1] == 2
+ # cp0 = 0 - a2 * b1 (b2 = 0)
+ # cp1 = a2 * b0 - 0 (b2 = 0)
+ multiply(a2, b1, out=cp0)
+ negative(cp0, out=cp0)
+ return moveaxis(cp, -1, axisc)
+little_endian = (sys.byteorder == 'little')
+def indices(dimensions, dtype=int, sparse=False):
+ Return an array representing the indices of a grid.
+ Compute an array where the subarrays contain index values 0, 1, ...
+ varying only along the corresponding axis.
+ dimensions : sequence of ints
+ The shape of the grid.
+ Data type of the result.
+ sparse : boolean, optional
+ Return a sparse representation of the grid instead of a dense
+ representation. Default is False.
+ .. versionadded:: 1.17
+ grid : one ndarray or tuple of ndarrays
+ If sparse is False:
+ Returns one array of grid indices,
+ ``grid.shape = (len(dimensions),) + tuple(dimensions)``.
+ If sparse is True:
+ Returns a tuple of arrays, with
+ ``grid[i].shape = (1, ..., 1, dimensions[i], 1, ..., 1)`` with
+ dimensions[i] in the ith place
+ mgrid, ogrid, meshgrid
+ The output shape in the dense case is obtained by prepending the number
+ of dimensions in front of the tuple of dimensions, i.e. if `dimensions`
+ is a tuple ``(r0, ..., rN-1)`` of length ``N``, the output shape is
+ ``(N, r0, ..., rN-1)``.
+ The subarrays ``grid[k]`` contains the N-D array of indices along the
+ ``k-th`` axis. Explicitly::
+ grid[k, i0, i1, ..., iN-1] = ik
+ >>> grid = np.indices((2, 3))
+ >>> grid.shape
+ (2, 2, 3)
+ >>> grid[0] # row indices
+ >>> grid[1] # column indices
+ [0, 1, 2]])
+ The indices can be used as an index into an array.
+ >>> x = np.arange(20).reshape(5, 4)
+ >>> row, col = np.indices((2, 3))
+ >>> x[row, col]
+ Note that it would be more straightforward in the above example to
+ extract the required elements directly with ``x[:2, :3]``.
+ If sparse is set to true, the grid will be returned in a sparse
+ >>> i, j = np.indices((2, 3), sparse=True)
+ >>> i.shape
+ (2, 1)
+ >>> j.shape
+ >>> i # row indices
+ >>> j # column indices
+ array([[0, 1, 2]])
+ dimensions = tuple(dimensions)
+ N = len(dimensions)
+ shape = (1,)*N
+ if sparse:
+ res = tuple()
+ res = empty((N,)+dimensions, dtype=dtype)
+ for i, dim in enumerate(dimensions):
+ idx = arange(dim, dtype=dtype).reshape(
+ shape[:i] + (dim,) + shape[i+1:]
+ res = res + (idx,)
+ res[i] = idx
+def _fromfunction_dispatcher(function, shape, *, dtype=None, like=None, **kwargs):
+def fromfunction(function, shape, *, dtype=float, like=None, **kwargs):
+ Construct an array by executing a function over each coordinate.
+ The resulting array therefore has a value ``fn(x, y, z)`` at
+ coordinate ``(x, y, z)``.
+ function : callable
+ The function is called with N parameters, where N is the rank of
+ `shape`. Each parameter represents the coordinates of the array
+ varying along a specific axis. For example, if `shape`
+ were ``(2, 2)``, then the parameters would be
+ ``array([[0, 0], [1, 1]])`` and ``array([[0, 1], [0, 1]])``
+ shape : (N,) tuple of ints
+ Shape of the output array, which also determines the shape of
+ the coordinate arrays passed to `function`.
+ Data-type of the coordinate arrays passed to `function`.
+ By default, `dtype` is float.
+ fromfunction : any
+ The result of the call to `function` is passed back directly.
+ Therefore the shape of `fromfunction` is completely determined by
+ `function`. If `function` returns a scalar value, the shape of
+ `fromfunction` would not match the `shape` parameter.
+ indices, meshgrid
+ Keywords other than `dtype` are passed to `function`.
+ >>> np.fromfunction(lambda i, j: i == j, (3, 3), dtype=int)
+ array([[ True, False, False],
+ [False, True, False],
+ [False, False, True]])
+ >>> np.fromfunction(lambda i, j: i + j, (3, 3), dtype=int)
+ [1, 2, 3],
+ [2, 3, 4]])
+ return _fromfunction_with_like(function, shape, dtype=dtype, like=like, **kwargs)
+ args = indices(shape, dtype=dtype)
+ return function(*args, **kwargs)
+_fromfunction_with_like = array_function_dispatch(
+ _fromfunction_dispatcher
+)(fromfunction)
+def _frombuffer(buf, dtype, shape, order):
+ return frombuffer(buf, dtype=dtype).reshape(shape, order=order)
+def isscalar(element):
+ Returns True if the type of `element` is a scalar type.
+ element : any
+ Input argument, can be of any type and shape.
+ val : bool
+ True if `element` is a scalar type, False if it is not.
+ ndim : Get the number of dimensions of an array
+ If you need a stricter way to identify a *numerical* scalar, use
+ ``isinstance(x, numbers.Number)``, as that returns ``False`` for most
+ non-numerical elements such as strings.
+ In most cases ``np.ndim(x) == 0`` should be used instead of this function,
+ as that will also return true for 0d arrays. This is how numpy overloads
+ functions in the style of the ``dx`` arguments to `gradient` and the ``bins``
+ argument to `histogram`. Some key differences:
+ +--------------------------------------+---------------+-------------------+
+ | x |``isscalar(x)``|``np.ndim(x) == 0``|
+ +======================================+===============+===================+
+ | PEP 3141 numeric objects (including | ``True`` | ``True`` |
+ | builtins) | | |
+ | builtin string and buffer objects | ``True`` | ``True`` |
+ | other builtin objects, like | ``False`` | ``True`` |
+ | `pathlib.Path`, `Exception`, | | |
+ | the result of `re.compile` | | |
+ | third-party objects like | ``False`` | ``True`` |
+ | `matplotlib.figure.Figure` | | |
+ | zero-dimensional numpy arrays | ``False`` | ``True`` |
+ | other numpy arrays | ``False`` | ``False`` |
+ | `list`, `tuple`, and other sequence | ``False`` | ``False`` |
+ | objects | | |
+ >>> np.isscalar(3.1)
+ >>> np.isscalar(np.array(3.1))
+ >>> np.isscalar([3.1])
+ >>> np.isscalar(False)
+ >>> np.isscalar('numpy')
+ NumPy supports PEP 3141 numbers:
+ >>> from fractions import Fraction
+ >>> np.isscalar(Fraction(5, 17))
+ >>> from numbers import Number
+ >>> np.isscalar(Number())
+ return (isinstance(element, generic)
+ or type(element) in ScalarType
+ or isinstance(element, numbers.Number))
+def binary_repr(num, width=None):
+ Return the binary representation of the input number as a string.
+ For negative numbers, if width is not given, a minus sign is added to the
+ front. If width is given, the two's complement of the number is
+ returned, with respect to that width.
+ In a two's-complement system negative numbers are represented by the two's
+ complement of the absolute value. This is the most common method of
+ representing signed integers on computers [1]_. A N-bit two's-complement
+ system can represent every integer in the range
+ :math:`-2^{N-1}` to :math:`+2^{N-1}-1`.
+ num : int
+ Only an integer decimal number can be used.
+ width : int, optional
+ The length of the returned string if `num` is positive, or the length
+ of the two's complement if `num` is negative, provided that `width` is
+ at least a sufficient number of bits for `num` to be represented in the
+ designated form.
+ If the `width` value is insufficient, it will be ignored, and `num` will
+ be returned in binary (`num` > 0) or two's complement (`num` < 0) form
+ with its width equal to the minimum number of bits needed to represent
+ the number in the designated form. This behavior is deprecated and will
+ later raise an error.
+ .. deprecated:: 1.12.0
+ bin : str
+ Binary representation of `num` or two's complement of `num`.
+ base_repr: Return a string representation of a number in the given base
+ system.
+ bin: Python's built-in binary representation generator of an integer.
+ `binary_repr` is equivalent to using `base_repr` with base 2, but about 25x
+ faster.
+ .. [1] Wikipedia, "Two's complement",
+ https://en.wikipedia.org/wiki/Two's_complement
+ >>> np.binary_repr(3)
+ '11'
+ >>> np.binary_repr(-3)
+ '-11'
+ >>> np.binary_repr(3, width=4)
+ '0011'
+ The two's complement is returned when the input number is negative and
+ width is specified:
+ >>> np.binary_repr(-3, width=3)
+ '101'
+ >>> np.binary_repr(-3, width=5)
+ '11101'
+ def warn_if_insufficient(width, binwidth):
+ if width is not None and width < binwidth:
+ "Insufficient bit width provided. This behavior "
+ "will raise an error in the future.", DeprecationWarning,
+ # Ensure that num is a Python integer to avoid overflow or unwanted
+ # casts to floating point.
+ if num == 0:
+ return '0' * (width or 1)
+ elif num > 0:
+ binary = bin(num)[2:]
+ binwidth = len(binary)
+ outwidth = (binwidth if width is None
+ else max(binwidth, width))
+ warn_if_insufficient(width, binwidth)
+ return binary.zfill(outwidth)
+ if width is None:
+ return '-' + bin(-num)[2:]
+ poswidth = len(bin(-num)[2:])
+ # See gh-8679: remove extra digit
+ # for numbers at boundaries.
+ if 2**(poswidth - 1) == -num:
+ poswidth -= 1
+ twocomp = 2**(poswidth + 1) + num
+ binary = bin(twocomp)[2:]
+ outwidth = max(binwidth, width)
+ return '1' * (outwidth - binwidth) + binary
+def base_repr(number, base=2, padding=0):
+ Return a string representation of a number in the given base system.
+ number : int
+ The value to convert. Positive and negative values are handled.
+ base : int, optional
+ Convert `number` to the `base` number system. The valid range is 2-36,
+ the default value is 2.
+ padding : int, optional
+ Number of zeros padded on the left. Default is 0 (no padding).
+ out : str
+ String representation of `number` in `base` system.
+ binary_repr : Faster version of `base_repr` for base 2.
+ >>> np.base_repr(5)
+ >>> np.base_repr(6, 5)
+ >>> np.base_repr(7, base=5, padding=3)
+ '00012'
+ >>> np.base_repr(10, base=16)
+ 'A'
+ >>> np.base_repr(32, base=16)
+ '20'
+ digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+ if base > len(digits):
+ raise ValueError("Bases greater than 36 not handled in base_repr.")
+ elif base < 2:
+ raise ValueError("Bases less than 2 not handled in base_repr.")
+ num = abs(number)
+ res = []
+ while num:
+ res.append(digits[num % base])
+ num //= base
+ if padding:
+ res.append('0' * padding)
+ if number < 0:
+ res.append('-')
+ return ''.join(reversed(res or '0'))
+# These are all essentially abbreviations
+# These might wind up in a special abbreviations module
+def _maketup(descr, val):
+ dt = dtype(descr)
+ # Place val in all scalar tuples:
+ fields = dt.fields
+ res = [_maketup(fields[name][0], val) for name in dt.names]
+ return tuple(res)
+def _identity_dispatcher(n, dtype=None, *, like=None):
+def identity(n, dtype=None, *, like=None):
+ Return the identity array.
+ The identity array is a square array with ones on
+ the main diagonal.
+ n : int
+ Number of rows (and columns) in `n` x `n` output.
+ Data-type of the output. Defaults to ``float``.
+ `n` x `n` array with its main diagonal set to one,
+ and all other elements 0.
+ >>> np.identity(3)
+ return _identity_with_like(n, dtype=dtype, like=like)
+ from numpy import eye
+ return eye(n, dtype=dtype, like=like)
+_identity_with_like = array_function_dispatch(
+ _identity_dispatcher
+)(identity)
+def _allclose_dispatcher(a, b, rtol=None, atol=None, equal_nan=None):
+@array_function_dispatch(_allclose_dispatcher)
+def allclose(a, b, rtol=1.e-5, atol=1.e-8, equal_nan=False):
+ Returns True if two arrays are element-wise equal within a tolerance.
+ The tolerance values are positive, typically very small numbers. The
+ relative difference (`rtol` * abs(`b`)) and the absolute difference
+ `atol` are added together to compare against the absolute difference
+ between `a` and `b`.
+ NaNs are treated as equal if they are in the same place and if
+ ``equal_nan=True``. Infs are treated as equal if they are in the same
+ place and of the same sign in both arrays.
+ Input arrays to compare.
+ rtol : float
+ The relative tolerance parameter (see Notes).
+ atol : float
+ The absolute tolerance parameter (see Notes).
+ equal_nan : bool
+ Whether to compare NaN's as equal. If True, NaN's in `a` will be
+ considered equal to NaN's in `b` in the output array.
+ allclose : bool
+ Returns True if the two arrays are equal within the given
+ tolerance; False otherwise.
+ isclose, all, any, equal
+ If the following equation is element-wise True, then allclose returns
+ True.
+ absolute(`a` - `b`) <= (`atol` + `rtol` * absolute(`b`))
+ The above equation is not symmetric in `a` and `b`, so that
+ ``allclose(a, b)`` might be different from ``allclose(b, a)`` in
+ some rare cases.
+ The comparison of `a` and `b` uses standard broadcasting, which
+ means that `a` and `b` need not have the same shape in order for
+ ``allclose(a, b)`` to evaluate to True. The same is true for
+ `equal` but not `array_equal`.
+ `allclose` is not defined for non-numeric data types.
+ >>> np.allclose([1e10,1e-7], [1.00001e10,1e-8])
+ >>> np.allclose([1e10,1e-8], [1.00001e10,1e-9])
+ >>> np.allclose([1e10,1e-8], [1.0001e10,1e-9])
+ >>> np.allclose([1.0, np.nan], [1.0, np.nan])
+ >>> np.allclose([1.0, np.nan], [1.0, np.nan], equal_nan=True)
+ res = all(isclose(a, b, rtol=rtol, atol=atol, equal_nan=equal_nan))
+ return bool(res)
+def _isclose_dispatcher(a, b, rtol=None, atol=None, equal_nan=None):
+@array_function_dispatch(_isclose_dispatcher)
+def isclose(a, b, rtol=1.e-5, atol=1.e-8, equal_nan=False):
+ Returns a boolean array where two arrays are element-wise equal within a
+ tolerance.
+ .. warning:: The default `atol` is not appropriate for comparing numbers
+ that are much smaller than one (see Notes).
+ Returns a boolean array of where `a` and `b` are equal within the
+ given tolerance. If both `a` and `b` are scalars, returns a single
+ boolean value.
+ allclose
+ math.isclose
+ For finite values, isclose uses the following equation to test whether
+ two floating point values are equivalent.
+ Unlike the built-in `math.isclose`, the above equation is not symmetric
+ in `a` and `b` -- it assumes `b` is the reference value -- so that
+ `isclose(a, b)` might be different from `isclose(b, a)`. Furthermore,
+ the default value of atol is not zero, and is used to determine what
+ small values should be considered close to zero. The default value is
+ appropriate for expected values of order unity: if the expected values
+ are significantly smaller than one, it can result in false positives.
+ `atol` should be carefully selected for the use case at hand. A zero value
+ for `atol` will result in `False` if either `a` or `b` is zero.
+ `isclose` is not defined for non-numeric data types.
+ >>> np.isclose([1e10,1e-7], [1.00001e10,1e-8])
+ >>> np.isclose([1e10,1e-8], [1.00001e10,1e-9])
+ array([ True, True])
+ >>> np.isclose([1e10,1e-8], [1.0001e10,1e-9])
+ >>> np.isclose([1.0, np.nan], [1.0, np.nan])
+ >>> np.isclose([1.0, np.nan], [1.0, np.nan], equal_nan=True)
+ >>> np.isclose([1e-8, 1e-7], [0.0, 0.0])
+ >>> np.isclose([1e-100, 1e-7], [0.0, 0.0], atol=0.0)
+ array([False, False])
+ >>> np.isclose([1e-10, 1e-10], [1e-20, 0.0])
+ >>> np.isclose([1e-10, 1e-10], [1e-20, 0.999999e-10], atol=0.0)
+ def within_tol(x, y, atol, rtol):
+ return less_equal(abs(x-y), atol + rtol * abs(y))
+ x = asanyarray(a)
+ y = asanyarray(b)
+ # 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).
+ # 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 = array(y, dtype=dt, copy=False, subok=True)
+ xfin = isfinite(x)
+ yfin = isfinite(y)
+ if all(xfin) and all(yfin):
+ return within_tol(x, y, atol, rtol)
+ finite = xfin & yfin
+ cond = zeros_like(finite, subok=True)
+ # Because we're using boolean indexing, x & y must be the same shape.
+ # Ideally, we'd just do x, y = broadcast_arrays(x, y). It's in
+ # lib.stride_tricks, though, so we can't import it here.
+ x = x * ones_like(cond)
+ y = y * ones_like(cond)
+ # Avoid subtraction with infinite/nan values...
+ cond[finite] = within_tol(x[finite], y[finite], atol, rtol)
+ # Check for equality of infinite values...
+ cond[~finite] = (x[~finite] == y[~finite])
+ if equal_nan:
+ # Make NaN == NaN
+ both_nan = isnan(x) & isnan(y)
+ # Needed to treat masked arrays correctly. = True would not work.
+ cond[both_nan] = both_nan[both_nan]
+ return cond[()] # Flatten 0d arrays to scalars
+def _array_equal_dispatcher(a1, a2, equal_nan=None):
+ return (a1, a2)
+@array_function_dispatch(_array_equal_dispatcher)
+def array_equal(a1, a2, equal_nan=False):
+ True if two arrays have the same shape and elements, False otherwise.
+ a1, a2 : array_like
+ Whether to compare NaN's as equal. If the dtype of a1 and a2 is
+ complex, values will be considered equal if either the real or the
+ imaginary component of a given value is ``nan``.
+ b : bool
+ Returns True if the arrays are equal.
+ allclose: Returns True if two arrays are element-wise equal within a
+ array_equiv: Returns True if input arrays are shape consistent and all
+ elements equal.
+ >>> np.array_equal([1, 2], [1, 2])
+ >>> np.array_equal(np.array([1, 2]), np.array([1, 2]))
+ >>> np.array_equal([1, 2], [1, 2, 3])
+ >>> np.array_equal([1, 2], [1, 4])
+ >>> a = np.array([1, np.nan])
+ >>> np.array_equal(a, a)
+ >>> np.array_equal(a, a, equal_nan=True)
+ When ``equal_nan`` is True, complex values with nan components are
+ considered equal if either the real *or* the imaginary components are nan.
+ >>> a = np.array([1 + 1j])
+ >>> b = a.copy()
+ >>> a.real = np.nan
+ >>> b.imag = np.nan
+ >>> np.array_equal(a, b, equal_nan=True)
+ a1, a2 = asarray(a1), asarray(a2)
+ if a1.shape != a2.shape:
+ if not equal_nan:
+ return bool(asarray(a1 == a2).all())
+ # Handling NaN values if equal_nan is True
+ a1nan, a2nan = isnan(a1), isnan(a2)
+ # NaN's occur at different locations
+ if not (a1nan == a2nan).all():
+ # Shapes of a1, a2 and masks are guaranteed to be consistent by this point
+ return bool(asarray(a1[~a1nan] == a2[~a1nan]).all())
+def _array_equiv_dispatcher(a1, a2):
+@array_function_dispatch(_array_equiv_dispatcher)
+def array_equiv(a1, a2):
+ Returns True if input arrays are shape consistent and all elements equal.
+ Shape consistent means they are either the same shape, or one input array
+ can be broadcasted to create the same shape as the other one.
+ True if equivalent, False otherwise.
+ >>> np.array_equiv([1, 2], [1, 2])
+ >>> np.array_equiv([1, 2], [1, 3])
+ Showing the shape equivalence:
+ >>> np.array_equiv([1, 2], [[1, 2], [1, 2]])
+ >>> np.array_equiv([1, 2], [[1, 2, 1, 2], [1, 2, 1, 2]])
+ >>> np.array_equiv([1, 2], [[1, 2], [1, 3]])
+ multiarray.broadcast(a1, a2)
+Inf = inf = infty = Infinity = PINF
+nan = NaN = NAN
+False_ = bool_(False)
+True_ = bool_(True)
+def extend_all(module):
+ existing = set(__all__)
+ mall = getattr(module, '__all__')
+ for a in mall:
+ if a not in existing:
+ __all__.append(a)
+from .umath import *
+from .numerictypes import *
+from . import arrayprint
+from .arrayprint import *
+from . import _asarray
+from ._asarray import *
+from . import _ufunc_config
+from ._ufunc_config import *
+extend_all(fromnumeric)
+extend_all(umath)
+extend_all(numerictypes)
+extend_all(arrayprint)
+extend_all(_asarray)
+extend_all(_ufunc_config)
+from numpy import ndarray, generic, dtype, bool_, signedinteger, _OrderKACF, _OrderCF
+from numpy.typing import ArrayLike, DTypeLike, _ShapeLike
+_T = TypeVar("_T")
+_CorrelateMode = Literal["valid", "same", "full"]
+def zeros_like(
+ subok: Literal[True] = ...,
+ shape: None = ...,
+ shape: Optional[_ShapeLike] = ...,
+def ones(
+def ones_like(
+def empty_like(
+def full(
+ fill_value: Any,
+def full_like(
+def count_nonzero(
+) -> int: ...
+) -> 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(
+ mode: _CorrelateMode = ...,
+def convolve(
+def outer(
+ b: ArrayLike,
+ out: _ArrayType = ...,
+def tensordot(
+ axes: Union[int, Tuple[_ShapeLike, _ShapeLike]] = ...,
+def roll(
+ shift: _ShapeLike,
+def rollaxis(a: ndarray, axis: int, start: int = ...) -> ndarray: ...
+def moveaxis(
+ source: _ShapeLike,
+ destination: _ShapeLike,
+def cross(
+ axisa: int = ...,
+ axisb: int = ...,
+ axisc: int = ...,
+def indices(
+ dimensions: Sequence[int],
+ sparse: Literal[False] = ...,
+ sparse: Literal[True] = ...,
+) -> Tuple[ndarray, ...]: ...
+def fromfunction(
+ function: Callable[..., _T],
+ shape: Sequence[int],
+) -> _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,
+def allclose(
+ rtol: float = ...,
+ atol: float = ...,
+ equal_nan: bool = ...,
+) -> bool: ...
+def isclose(
+def array_equal(a1: ArrayLike, a2: ArrayLike) -> bool: ...
+def array_equiv(a1: ArrayLike, a2: ArrayLike) -> bool: ...
@@ -0,0 +1,672 @@
+numerictypes: Define the numeric type objects
+This module is designed so "from numerictypes import \\*" is safe.
+Exported symbols include:
+ Dictionary with all registered number types (including aliases):
+ typeDict
+ Type objects (not all will be available, depends on platform):
+ see variable sctypes for which ones you have
+ Bit-width names
+ int8 int16 int32 int64 int128
+ uint8 uint16 uint32 uint64 uint128
+ float16 float32 float64 float96 float128 float256
+ complex32 complex64 complex128 complex192 complex256 complex512
+ datetime64 timedelta64
+ c-based names
+ bool_
+ object_
+ void, str_, unicode_
+ byte, ubyte,
+ short, ushort
+ intc, uintc,
+ intp, uintp,
+ int_, uint,
+ longlong, ulonglong,
+ single, csingle,
+ float_, complex_,
+ longfloat, clongfloat,
+ As part of the type-hierarchy: xx -- is bit-width
+ generic
+ +-> bool_ (kind=b)
+ +-> number
+ | +-> integer
+ | | +-> signedinteger (intxx) (kind=i)
+ | | | byte
+ | | | short
+ | | | intc
+ | | | intp int0
+ | | | int_
+ | | | longlong
+ | | \\-> unsignedinteger (uintxx) (kind=u)
+ | | ubyte
+ | | ushort
+ | | uintc
+ | | uintp uint0
+ | | uint_
+ | | ulonglong
+ | +-> inexact
+ | +-> floating (floatxx) (kind=f)
+ | | half
+ | | single
+ | | float_ (double)
+ | | longfloat
+ | \\-> complexfloating (complexxx) (kind=c)
+ | csingle (singlecomplex)
+ | complex_ (cfloat, cdouble)
+ | clongfloat (longcomplex)
+ +-> flexible
+ | +-> character
+ | | str_ (string_, bytes_) (kind=S) [Python 2]
+ | | unicode_ (kind=U) [Python 2]
+ | |
+ | | bytes_ (string_) (kind=S) [Python 3]
+ | | str_ (unicode_) (kind=U) [Python 3]
+ | \\-> void (kind=V)
+ \\-> object_ (not used much) (kind=O)
+import types as _types
+from numpy.core.multiarray import (
+ typeinfo, ndarray, array, empty, dtype, datetime_data,
+ datetime_as_string, busday_offset, busday_count, is_busday,
+ busdaycalendar
+# we add more at the bottom
+__all__ = ['sctypeDict', 'typeDict', 'sctypes',
+ 'ScalarType', 'obj2sctype', 'cast', 'nbytes', 'sctype2char',
+ 'maximum_sctype', 'issctype', 'typecodes', 'find_common_type',
+ 'issubdtype', 'datetime_data', 'datetime_as_string',
+ 'busday_offset', 'busday_count', 'is_busday', 'busdaycalendar',
+# we don't need all these imports, but we need to keep them for compatibility
+# for users using np.core.numerictypes.UPPER_TABLE
+from ._string_helpers import (
+ english_lower, english_upper, english_capitalize, LOWER_TABLE, UPPER_TABLE
+from ._type_aliases import (
+ sctypeDict,
+ allTypes,
+ bitname,
+ sctypes,
+ _concrete_types,
+ _concrete_typeinfo,
+ _bits_of,
+from ._dtype import _kind_name
+# we don't export these for import *, but we do want them accessible
+# as numerictypes.bool, etc.
+from builtins import bool, int, float, complex, object, str, bytes
+from numpy.compat import long, unicode
+# We use this later
+generic = allTypes['generic']
+genericTypeRank = ['bool', 'int8', 'uint8', 'int16', 'uint16',
+ 'int32', 'uint32', 'int64', 'uint64', 'int128',
+ 'uint128', 'float16',
+ 'float32', 'float64', 'float80', 'float96', 'float128',
+ 'float256',
+ 'complex32', 'complex64', 'complex128', 'complex160',
+ 'complex192', 'complex256', 'complex512', 'object']
+def maximum_sctype(t):
+ Return the scalar type of highest precision of the same kind as the input.
+ t : dtype or dtype specifier
+ The input data type. This can be a `dtype` object or an object that
+ is convertible to a `dtype`.
+ The highest precision data type of the same kind (`dtype.kind`) as `t`.
+ obj2sctype, mintypecode, sctype2char
+ >>> np.maximum_sctype(int)
+ <class 'numpy.int64'>
+ >>> np.maximum_sctype(np.uint8)
+ <class 'numpy.uint64'>
+ >>> np.maximum_sctype(complex)
+ <class 'numpy.complex256'> # may vary
+ >>> np.maximum_sctype(str)
+ <class 'numpy.str_'>
+ >>> np.maximum_sctype('i2')
+ >>> np.maximum_sctype('f4')
+ <class 'numpy.float128'> # may vary
+ g = obj2sctype(t)
+ if g is None:
+ return t
+ t = g
+ base = _kind_name(dtype(t))
+ if base in sctypes:
+ return sctypes[base][-1]
+def issctype(rep):
+ Determines whether the given object represents a scalar data-type.
+ rep : any
+ If `rep` is an instance of a scalar dtype, True is returned. If not,
+ False is returned.
+ Boolean result of check whether `rep` is a scalar dtype.
+ issubsctype, issubdtype, obj2sctype, sctype2char
+ >>> np.issctype(np.int32)
+ >>> np.issctype(list)
+ >>> np.issctype(1.1)
+ Strings are also a scalar type:
+ >>> np.issctype(np.dtype('str'))
+ if not isinstance(rep, (type, dtype)):
+ res = obj2sctype(rep)
+ if res and res != object_:
+def obj2sctype(rep, default=None):
+ Return the scalar dtype or NumPy equivalent of Python type of an object.
+ The object of which the type is returned.
+ default : any, optional
+ If given, this is returned for objects whose types can not be
+ determined. If not given, None is returned for those objects.
+ dtype : dtype or Python type
+ The data type of `rep`.
+ sctype2char, issctype, issubsctype, issubdtype, maximum_sctype
+ >>> np.obj2sctype(np.int32)
+ <class 'numpy.int32'>
+ >>> np.obj2sctype(np.array([1., 2.]))
+ <class 'numpy.float64'>
+ >>> np.obj2sctype(np.array([1.j]))
+ <class 'numpy.complex128'>
+ >>> np.obj2sctype(dict)
+ <class 'numpy.object_'>
+ >>> np.obj2sctype('string')
+ >>> np.obj2sctype(1, default=list)
+ <class 'list'>
+ # prevent abstract classes being upcast
+ if isinstance(rep, type) and issubclass(rep, generic):
+ return rep
+ # extract dtype from arrays
+ if isinstance(rep, ndarray):
+ return rep.dtype.type
+ # fall back on dtype to convert
+ res = dtype(rep)
+ return default
+ return res.type
+def issubclass_(arg1, arg2):
+ Determine if a class is a subclass of a second class.
+ `issubclass_` is equivalent to the Python built-in ``issubclass``,
+ except that it returns False instead of raising a TypeError if one
+ of the arguments is not a class.
+ arg1 : class
+ Input class. True is returned if `arg1` is a subclass of `arg2`.
+ arg2 : class or tuple of classes.
+ Input class. If a tuple of classes, True is returned if `arg1` is a
+ subclass of any of the tuple elements.
+ Whether `arg1` is a subclass of `arg2` or not.
+ issubsctype, issubdtype, issctype
+ >>> np.issubclass_(np.int32, int)
+ >>> np.issubclass_(np.int32, float)
+ >>> np.issubclass_(np.float64, float)
+ return issubclass(arg1, arg2)
+def issubsctype(arg1, arg2):
+ Determine if the first argument is a subclass of the second argument.
+ arg1, arg2 : dtype or dtype specifier
+ Data-types.
+ The result.
+ issctype, issubdtype, obj2sctype
+ >>> np.issubsctype('S8', str)
+ >>> np.issubsctype(np.array([1]), int)
+ >>> np.issubsctype(np.array([1]), float)
+ return issubclass(obj2sctype(arg1), obj2sctype(arg2))
+def issubdtype(arg1, arg2):
+ Returns True if first argument is a typecode lower/equal in type hierarchy.
+ This is like the builtin :func:`issubclass`, but for `dtype`\ s.
+ arg1, arg2 : dtype_like
+ `dtype` or object coercible to one
+ :ref:`arrays.scalars` : Overview of the numpy type hierarchy.
+ issubsctype, issubclass_
+ `issubdtype` can be used to check the type of arrays:
+ >>> ints = np.array([1, 2, 3], dtype=np.int32)
+ >>> np.issubdtype(ints.dtype, np.integer)
+ >>> np.issubdtype(ints.dtype, np.floating)
+ >>> floats = np.array([1, 2, 3], dtype=np.float32)
+ >>> np.issubdtype(floats.dtype, np.integer)
+ >>> np.issubdtype(floats.dtype, np.floating)
+ Similar types of different sizes are not subdtypes of each other:
+ >>> np.issubdtype(np.float64, np.float32)
+ >>> np.issubdtype(np.float32, np.float64)
+ but both are subtypes of `floating`:
+ >>> np.issubdtype(np.float64, np.floating)
+ >>> np.issubdtype(np.float32, np.floating)
+ For convenience, dtype-like objects are allowed too:
+ >>> np.issubdtype('S1', np.string_)
+ >>> np.issubdtype('i4', np.signedinteger)
+ if not issubclass_(arg1, generic):
+ arg1 = dtype(arg1).type
+ if not issubclass_(arg2, generic):
+ arg2 = dtype(arg2).type
+# This dictionary allows look up based on any alias for an array data-type
+class _typedict(dict):
+ Base object for a dictionary for look-up with any alias for an array dtype.
+ Instances of `_typedict` can not be used as dictionaries directly,
+ first they have to be populated.
+ return dict.__getitem__(self, obj2sctype(obj))
+nbytes = _typedict()
+_alignment = _typedict()
+_maxvals = _typedict()
+_minvals = _typedict()
+def _construct_lookups():
+ obj = info.type
+ nbytes[obj] = info.bits // 8
+ _alignment[obj] = info.alignment
+ if len(info) > 5:
+ _maxvals[obj] = info.max
+ _minvals[obj] = info.min
+ _maxvals[obj] = None
+ _minvals[obj] = None
+_construct_lookups()
+def sctype2char(sctype):
+ Return the string representation of a scalar dtype.
+ sctype : scalar dtype or object
+ If a scalar dtype, the corresponding string character is
+ returned. If an object, `sctype2char` tries to infer its scalar type
+ and then return the corresponding string character.
+ typechar : str
+ The string character corresponding to the scalar type.
+ If `sctype` is an object for which the type can not be inferred.
+ obj2sctype, issctype, issubsctype, mintypecode
+ >>> for sctype in [np.int32, np.double, np.complex_, np.string_, np.ndarray]:
+ ... print(np.sctype2char(sctype))
+ l # may vary
+ d
+ D
+ S
+ O
+ >>> x = np.array([1., 2-1.j])
+ >>> np.sctype2char(x)
+ 'D'
+ >>> np.sctype2char(list)
+ 'O'
+ sctype = obj2sctype(sctype)
+ if sctype is None:
+ raise ValueError("unrecognized type")
+ if sctype not in _concrete_types:
+ # for compatibility
+ raise KeyError(sctype)
+ return dtype(sctype).char
+# Create dictionary of casting functions that wrap sequences
+# indexed by type or type character
+cast = _typedict()
+for key in _concrete_types:
+ cast[key] = lambda x, k=key: array(x, copy=False).astype(k)
+ 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)
+ScalarType = tuple(ScalarType)
+# Now add the types we've determined to this module
+for key in allTypes:
+ globals()[key] = allTypes[key]
+ __all__.append(key)
+del key
+typecodes = {'Character':'c',
+ 'Integer':'bhilqp',
+ 'UnsignedInteger':'BHILQP',
+ 'Float':'efdg',
+ 'Complex':'FDG',
+ 'AllInteger':'bBhHiIlLqQpP',
+ 'AllFloat':'efdgFDG',
+ 'Datetime': 'Mm',
+ 'All':'?bhilqpBHILQPefdgFDGSUVOMm'}
+# backwards compatibility --- deprecated name
+typeDict = sctypeDict
+# b -> boolean
+# u -> unsigned integer
+# i -> signed integer
+# f -> floating point
+# c -> complex
+# M -> datetime
+# m -> timedelta
+# S -> string
+# U -> Unicode string
+# V -> record
+# O -> Python object
+_kind_list = ['b', 'u', 'i', 'f', 'c', 'S', 'U', 'V', 'O', 'M', 'm']
+__test_types = '?'+typecodes['AllInteger'][:-2]+typecodes['AllFloat']+'O'
+__len_test_types = len(__test_types)
+# Keep incrementing until a common type both can be coerced to
+# is found. Otherwise, return None
+def _find_common_coerce(a, b):
+ if a > b:
+ thisind = __test_types.index(a.char)
+ return _can_coerce_all([a, b], start=thisind)
+# Find a data-type that all data-types in a list can be coerced to
+def _can_coerce_all(dtypelist, start=0):
+ N = len(dtypelist)
+ if N == 0:
+ if N == 1:
+ return dtypelist[0]
+ thisind = start
+ while thisind < __len_test_types:
+ newdtype = dtype(__test_types[thisind])
+ numcoerce = len([x for x in dtypelist if newdtype >= x])
+ if numcoerce == N:
+ return newdtype
+ thisind += 1
+def _register_types():
+ numbers.Integral.register(integer)
+ numbers.Complex.register(inexact)
+ numbers.Real.register(floating)
+ numbers.Number.register(number)
+_register_types()
+def find_common_type(array_types, scalar_types):
+ Determine common type following standard coercion rules.
+ array_types : sequence
+ A list of dtypes or dtype convertible objects representing arrays.
+ scalar_types : sequence
+ A list of dtypes or dtype convertible objects representing scalars.
+ datatype : dtype
+ The common data type, which is the maximum of `array_types` ignoring
+ `scalar_types`, unless the maximum of `scalar_types` is of a
+ different kind (`dtype.kind`). If the kind is not understood, then
+ None is returned.
+ dtype, common_type, can_cast, mintypecode
+ >>> np.find_common_type([], [np.int64, np.float32, complex])
+ >>> np.find_common_type([np.int64, np.float32], [])
+ The standard casting rules ensure that a scalar cannot up-cast an
+ array unless the scalar is of a fundamentally different kind of data
+ (i.e. under a different hierarchy in the data type hierarchy) then
+ the array:
+ >>> np.find_common_type([np.float32], [np.int64, np.float64])
+ Complex is of a different type, so it up-casts the float in the
+ `array_types` argument:
+ >>> np.find_common_type([np.float32], [complex])
+ Type specifier strings are convertible to dtypes and can therefore
+ be used instead of dtypes:
+ >>> np.find_common_type(['f4', 'f4', 'i4'], ['c8'])
+ array_types = [dtype(x) for x in array_types]
+ scalar_types = [dtype(x) for x in scalar_types]
+ maxa = _can_coerce_all(array_types)
+ maxsc = _can_coerce_all(scalar_types)
+ if maxa is None:
+ return maxsc
+ if maxsc is None:
+ return maxa
+ index_a = _kind_list.index(maxa.kind)
+ index_sc = _kind_list.index(maxsc.kind)
+ if index_sc > index_a:
+ return _find_common_coerce(maxsc, maxa)
+from typing import TypeVar, Optional, Type, Union, Tuple, Sequence, overload, Any
+from numpy import generic, ndarray, dtype
+from numpy.typing import DTypeLike
+_DefaultType = TypeVar("_DefaultType")
+def maximum_sctype(t: DTypeLike) -> dtype: ...
+def issctype(rep: object) -> bool: ...
+def obj2sctype(rep: object) -> Optional[generic]: ...
+def obj2sctype(rep: object, default: None) -> Optional[generic]: ...
+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]
+def issubdtype(arg1: DTypeLike, arg2: DTypeLike) -> bool: ...
+def sctype2char(sctype: object) -> str: ...
+def find_common_type(
+ array_types: Sequence[DTypeLike], scalar_types: Sequence[DTypeLike]
+) -> dtype: ...
+# TODO: Add annotations for the following objects:
+# typeDict, nbytes, cast, ScalarType & typecodes
@@ -0,0 +1,231 @@
+"""Implementation of __array_function__ overrides from NEP-18."""
+import collections
+import textwrap
+from numpy.core._multiarray_umath import (
+ add_docstring, implement_array_function, _get_implementing_args)
+from numpy.compat._inspect import getargspec
+ARRAY_FUNCTION_ENABLED = bool(
+ int(os.environ.get('NUMPY_EXPERIMENTAL_ARRAY_FUNCTION', 1)))
+array_function_like_doc = (
+ """like : array_like
+ Reference object to allow the creation of arrays which are not
+ 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.
+ The ``like`` keyword is an experimental feature pending on
+ acceptance of :ref:`NEP 35 <NEP35>`."""
+def set_array_function_like_doc(public_api):
+ if public_api.__doc__ is not None:
+ public_api.__doc__ = public_api.__doc__.replace(
+ return public_api
+add_docstring(
+ implement_array_function,
+ Implement a function with checks for __array_function__ overrides.
+ All arguments are required, and can only be passed by position.
+ implementation : function
+ Function that implements the operation on NumPy array without
+ overrides when called like ``implementation(*args, **kwargs)``.
+ public_api : function
+ Function exposed by NumPy's public API originally called like
+ ``public_api(*args, **kwargs)`` on which arguments are now being
+ checked.
+ relevant_args : iterable
+ Iterable of arguments to check for __array_function__ methods.
+ args : tuple
+ Arbitrary positional arguments originally passed into ``public_api``.
+ kwargs : dict
+ Arbitrary keyword arguments originally passed into ``public_api``.
+ Result from calling ``implementation()`` or an ``__array_function__``
+ method, as appropriate.
+ TypeError : if no implementation is found.
+# exposed for testing purposes; used internally by implement_array_function
+ _get_implementing_args,
+ Collect arguments on which to call __array_function__.
+ relevant_args : iterable of array-like
+ Iterable of possibly array-like arguments to check for
+ __array_function__ methods.
+ Sequence of arguments with __array_function__ methods, in the order in
+ which they should be called.
+ArgSpec = collections.namedtuple('ArgSpec', 'args varargs keywords defaults')
+def verify_matching_signatures(implementation, dispatcher):
+ """Verify that a dispatcher function has the right signature."""
+ implementation_spec = ArgSpec(*getargspec(implementation))
+ dispatcher_spec = ArgSpec(*getargspec(dispatcher))
+ if (implementation_spec.args != dispatcher_spec.args or
+ implementation_spec.varargs != dispatcher_spec.varargs or
+ implementation_spec.keywords != dispatcher_spec.keywords or
+ (bool(implementation_spec.defaults) !=
+ bool(dispatcher_spec.defaults)) or
+ (implementation_spec.defaults is not None and
+ len(implementation_spec.defaults) !=
+ len(dispatcher_spec.defaults))):
+ raise RuntimeError('implementation and dispatcher for %s have '
+ 'different function signatures' % implementation)
+ if implementation_spec.defaults is not None:
+ if dispatcher_spec.defaults != (None,) * len(dispatcher_spec.defaults):
+ raise RuntimeError('dispatcher functions can only use None for '
+ 'default argument values')
+def set_module(module):
+ """Decorator for overriding __module__ on a function or class.
+ Example usage::
+ @set_module('numpy')
+ def example():
+ assert example.__module__ == 'numpy'
+ def decorator(func):
+ if module is not None:
+ func.__module__ = module
+ return func
+ return decorator
+# Call textwrap.dedent here instead of in the function so as to avoid
+# calling dedent multiple times on the same text
+_wrapped_func_source = textwrap.dedent("""
+ @functools.wraps(implementation)
+ def {name}(*args, **kwargs):
+ relevant_args = dispatcher(*args, **kwargs)
+ return implement_array_function(
+ implementation, {name}, relevant_args, args, kwargs)
+def array_function_dispatch(dispatcher, module=None, verify=True,
+ docs_from_dispatcher=False):
+ """Decorator for adding dispatch with the __array_function__ protocol.
+ See NEP-18 for example usage.
+ dispatcher : callable
+ Function that when called like ``dispatcher(*args, **kwargs)`` with
+ arguments from the NumPy function call returns an iterable of
+ array-like arguments to check for ``__array_function__``.
+ module : str, optional
+ __module__ attribute to set on new function, e.g., ``module='numpy'``.
+ By default, module is copied from the decorated function.
+ verify : bool, optional
+ If True, verify the that the signature of the dispatcher and decorated
+ function signatures match exactly: all required and optional arguments
+ should appear in order with the same names, but the default values for
+ all optional arguments should be ``None``. Only disable verification
+ if the dispatcher's signature needs to deviate for some particular
+ reason, e.g., because the function has a signature like
+ ``func(*args, **kwargs)``.
+ docs_from_dispatcher : bool, optional
+ If True, copy docs from the dispatcher function onto the dispatched
+ function, rather than from the implementation. This is useful for
+ functions defined in C, which otherwise don't have docstrings.
+ Function suitable for decorating the implementation of a NumPy function.
+ if not ARRAY_FUNCTION_ENABLED:
+ def decorator(implementation):
+ if docs_from_dispatcher:
+ add_docstring(implementation, dispatcher.__doc__)
+ implementation.__module__ = module
+ return implementation
+ if verify:
+ verify_matching_signatures(implementation, dispatcher)
+ # Equivalently, we could define this function directly instead of using
+ # exec. This version has the advantage of giving the helper function a
+ # more interpettable name. Otherwise, the original function does not
+ # show up at all in many cases, e.g., if it's written in C or if the
+ # dispatcher gets an invalid keyword argument.
+ source = _wrapped_func_source.format(name=implementation.__name__)
+ source_object = compile(
+ source, filename='<__array_function__ internals>', mode='exec')
+ scope = {
+ 'implementation': implementation,
+ 'dispatcher': dispatcher,
+ 'functools': functools,
+ 'implement_array_function': implement_array_function,
+ exec(source_object, scope)
+ public_api = scope[implementation.__name__]
+ public_api.__module__ = module
+ public_api._implementation = implementation
+def array_function_from_dispatcher(
+ implementation, module=None, verify=True, docs_from_dispatcher=True):
+ """Like array_function_dispatcher, but with function arguments flipped."""
+ def decorator(dispatcher):
+ return array_function_dispatch(
+ dispatcher, module, verify=verify,
+ docs_from_dispatcher=docs_from_dispatcher)(implementation)