name: install dependencies
command: |
python3 -m venv venv
+ ln -s $(which python3) venv/bin/python3.6
. venv/bin/activate
pip install cython sphinx==1.8.5 matplotlib ipython
sudo apt-get update
Alexander Belopolsky <abalkin@enlnt.com> Alexander Belopolsky <a@enlnt.com>
Alexander Belopolsky <abalkin@enlnt.com> Alexander Belopolsky <a@enlnt.com>
Alexander Belopolsky <abalkin@enlnt.com> sasha <sasha@localhost>
+Alexander Jung <kontakt@ajung.name> aleju <kontakt@ajung.name>
Alexander Shadchin <alexandr.shadchin@gmail.com> Alexandr Shadchin <alexandr.shadchin@gmail.com>
Alexander Shadchin <alexandr.shadchin@gmail.com> shadchin <alexandr.shadchin@gmail.com>
Allan Haldane <allan.haldane@gmail.com> ahaldane <ealloc@gmail.com>
Kiko Correoso <kachine@protonmail.com> kikocorreoso <kikocorreoso@users.noreply.github.com>
Konrad Kapp <k_kapp@yahoo.com> k_kapp@yahoo.com <k_kapp@yahoo.com>
Kriti Singh <kritisingh1.ks@gmail.com> kritisingh1 <kritisingh1.ks@gmail.com>
+Kmol Yuan <pyslvs@gmail.com> Yuan <pyslvs@gmail.com>
Lars Buitinck <larsmans@gmail.com> Lars Buitinck <l.buitinck@esciencecenter.nl>
Lars Buitinck <larsmans@gmail.com> Lars Buitinck <L.J.Buitinck@uva.nl>
Lars GrĂ¼ter <lagru@mailbox.org> Lars G <lagru@mailbox.org>
apt:
packages: &common_packages
- gfortran
- - libatlas-dev
- libatlas-base-dev
# Speedup builds, particularly when USE_CHROOT=1
- eatmydata
python:
- 3.5
- 3.6
+ - 3.8-dev
matrix:
include:
- python: 3.7
PYVER:=$(shell python3 -c 'from sys import version_info as v; print("{0}.{1}".format(v[0], v[1]))')
PYTHON = python$(PYVER)
-NUMPYVER:=$(shell python3 -c "import numpy; print(numpy.version.git_revision[:10])")
-GITVER ?= $(shell cd ..; python3 -c "from setup import git_version; \
- print(git_version()[:10])")
-
# You can set these variables from the command line.
SPHINXOPTS ?=
SPHINXBUILD ?= LANG=C sphinx-build
$(SPHINXOPTS) source
.PHONY: help clean html web pickle htmlhelp latex changes linkcheck \
- dist dist-build gitwash-update version-check
+ dist dist-build gitwash-update version-check html-build latex-build
#------------------------------------------------------------------------------
-rm -rf build/*
find . -name generated -type d -prune -exec rm -rf "{}" ";"
-version-check:
-ifeq "$(GITVER)" "Unknown"
- # @echo sdist build with unlabeled sources
-else ifneq ($(NUMPYVER),$(GITVER))
- @echo installed numpy $(NUMPYVER) != current repo git version \'$(GITVER)\'
- @echo use '"make dist"' or '"GITVER=$(NUMPYVER) make $(MAKECMDGOALS) ..."'
- @exit 1
-else
- # for testing
- # @echo installed numpy $(NUMPYVER) matches git version $(GITVER); exit 1
-endif
-
gitwash-update:
rm -rf source/dev/gitwash
install -d source/dev/gitwash
INSTALL_PPH = $(INSTALL_DIR)/lib/python$(PYVER)/site-packages:$(INSTALL_DIR)/local/lib/python$(PYVER)/site-packages:$(INSTALL_DIR)/lib/python$(PYVER)/dist-packages:$(INSTALL_DIR)/local/lib/python$(PYVER)/dist-packages
UPLOAD_DIR=/srv/docs_scipy_org/doc/numpy-$(RELEASE)
-DIST_VARS=SPHINXBUILD="LANG=C PYTHONPATH=$(INSTALL_PPH) python$(PYVER) `which sphinx-build`" PYTHON="PYTHONPATH=$(INSTALL_PPH) python$(PYVER)" SPHINXOPTS="$(SPHINXOPTS)"
+DIST_VARS=SPHINXBUILD="LANG=C PYTHONPATH=$(INSTALL_PPH) python$(PYVER) `which sphinx-build`" PYTHON="PYTHONPATH=$(INSTALL_PPH) python$(PYVER)"
+
+NUMPYVER:=$(shell $(PYTHON) -c "import numpy; print(numpy.version.git_revision[:10])" 2>/dev/null)
+GITVER ?= $(shell cd ..; $(PYTHON) -c "from setup import git_version; \
+ print(git_version()[:10])")
+
+version-check:
+ifeq "$(GITVER)" "Unknown"
+ # @echo sdist build with unlabeled sources
+else ifeq ("", "$(NUMPYVER)")
+ @echo numpy not found, cannot build documentation without successful \"import numpy\"
+ @exit 1
+else ifneq ($(NUMPYVER),$(GITVER))
+ @echo installed numpy $(NUMPYVER) != current repo git version \'$(GITVER)\'
+ @echo use '"make dist"' or '"GITVER=$(NUMPYVER) make $(MAKECMDGOALS) ..."'
+ @exit 1
+else
+ # for testing
+ # @echo installed numpy $(NUMPYVER) matches git version $(GITVER); exit 1
+endif
+
dist:
make $(DIST_VARS) real-dist
-real-dist: dist-build html html-scipyorg
- test -d build/latex || make latex
+real-dist: dist-build html-build html-scipyorg
+ test -d build/latex || make latex-build
make -C build/latex all-pdf
- -test -d build/htmlhelp || make htmlhelp-build
-rm -rf build/dist
cp -r build/html-scipyorg build/dist
cd build/html && zip -9r ../dist/numpy-html.zip .
mkdir -p build
touch build/generate-stamp
-html: generate version-check
+html: version-check html-build
+html-build: generate
mkdir -p build/html build/doctrees
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) build/html $(FILES)
$(PYTHON) postprocess.py html build/html/*.html
mkdir -p build/qthelp build/doctrees
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) build/qthelp $(FILES)
-latex: generate version-check
+latex: version-check latex-build
+latex-build: generate
mkdir -p build/latex build/doctrees
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) build/latex $(FILES)
$(PYTHON) postprocess.py tex build/latex/*.tex
--- /dev/null
+
+Contributors
+============
+
+A total of 17 people contributed to this release. People with a "+" by their
+names contributed a patch for the first time.
+
+* Alexander Jung +
+* Allan Haldane
+* Charles Harris
+* Eric Wieser
+* Giuseppe Cuccu +
+* Hiroyuki V. Yamazaki
+* Jérémie du Boisberranger
+* Kmol Yuan +
+* Matti Picus
+* Max Bolingbroke +
+* Maxwell Aladago +
+* Oleksandr Pavlyk
+* Peter Andreas Entschev
+* Sergei Lebedev
+* Seth Troisi +
+* Vladimir Pershin +
+* Warren Weckesser
+
+Pull requests merged
+====================
+
+A total of 24 pull requests were merged for this release.
+
+* `#14156 <https://github.com/numpy/numpy/pull/14156>`__: TST: Allow fuss in testing strided/non-strided exp/log loops
+* `#14157 <https://github.com/numpy/numpy/pull/14157>`__: BUG: avx2_scalef_ps must be static
+* `#14158 <https://github.com/numpy/numpy/pull/14158>`__: BUG: Remove stray print that causes a SystemError on python 3.7.
+* `#14159 <https://github.com/numpy/numpy/pull/14159>`__: BUG: Fix DeprecationWarning in python 3.8.
+* `#14160 <https://github.com/numpy/numpy/pull/14160>`__: BLD: Add missing gcd/lcm definitions to npy_math.h
+* `#14161 <https://github.com/numpy/numpy/pull/14161>`__: DOC, BUILD: cleanups and fix (again) 'build dist'
+* `#14166 <https://github.com/numpy/numpy/pull/14166>`__: TST: Add 3.8-dev to travisCI testing.
+* `#14194 <https://github.com/numpy/numpy/pull/14194>`__: BUG: Remove the broken clip wrapper (Backport)
+* `#14198 <https://github.com/numpy/numpy/pull/14198>`__: DOC: Fix hermitian argument docs in svd.
+* `#14199 <https://github.com/numpy/numpy/pull/14199>`__: MAINT: Workaround for Intel compiler bug leading to failing test
+* `#14200 <https://github.com/numpy/numpy/pull/14200>`__: TST: Clean up of test_pocketfft.py
+* `#14201 <https://github.com/numpy/numpy/pull/14201>`__: BUG: Make advanced indexing result on read-only subclass writeable...
+* `#14236 <https://github.com/numpy/numpy/pull/14236>`__: BUG: Fixed default BitGenerator name
+* `#14237 <https://github.com/numpy/numpy/pull/14237>`__: ENH: add c-imported modules for freeze analysis in np.random
+* `#14296 <https://github.com/numpy/numpy/pull/14296>`__: TST: Pin pytest version to 5.0.1
+* `#14301 <https://github.com/numpy/numpy/pull/14301>`__: BUG: Fix leak in the f2py-generated module init and `PyMem_Del`...
+* `#14302 <https://github.com/numpy/numpy/pull/14302>`__: BUG: Fix formatting error in exception message
+* `#14307 <https://github.com/numpy/numpy/pull/14307>`__: MAINT: random: Match type of SeedSequence.pool_size to DEFAULT_POOL_SIZE.
+* `#14308 <https://github.com/numpy/numpy/pull/14308>`__: BUG: Fix numpy.random bug in platform detection
+* `#14309 <https://github.com/numpy/numpy/pull/14309>`__: ENH: Enable huge pages in all Linux builds
+* `#14330 <https://github.com/numpy/numpy/pull/14330>`__: BUG: Fix segfault in `random.permutation(x)` when x is a string.
+* `#14338 <https://github.com/numpy/numpy/pull/14338>`__: BUG: don't fail when lexsorting some empty arrays (#14228)
+* `#14339 <https://github.com/numpy/numpy/pull/14339>`__: BUG: Fix misuse of .names and .fields in various places (backport...
+* `#14345 <https://github.com/numpy/numpy/pull/14345>`__: BUG: fix behavior of structured_to_unstructured on non-trivial...
+* `#14350 <https://github.com/numpy/numpy/pull/14350>`__: REL: Prepare 1.17.1 release
--- /dev/null
+.. currentmodule:: numpy
+
+==========================
+NumPy 1.17.1 Release Notes
+==========================
+
+This release contains a number of fixes for bugs reported against NumPy 1.17.0
+along with a few documentation and build improvements. The Python versions
+supported are 3.5-3.7, note that Python 2.7 has been dropped. Python 3.8b3
+should work with the released source packages, but there are no future
+guarantees.
+
+Downstream developers should use Cython >= 0.29.13 for Python 3.8 support and
+OpenBLAS >= 3.7 to avoid problems on the Skylake architecture. The NumPy wheels
+on PyPI are built from the OpenBLAS development branch in order to avoid those
+problems.
+
+
+Contributors
+============
+
+A total of 17 people contributed to this release. People with a "+" by their
+names contributed a patch for the first time.
+
+* Alexander Jung +
+* Allan Haldane
+* Charles Harris
+* Eric Wieser
+* Giuseppe Cuccu +
+* Hiroyuki V. Yamazaki
+* Jérémie du Boisberranger
+* Kmol Yuan +
+* Matti Picus
+* Max Bolingbroke +
+* Maxwell Aladago +
+* Oleksandr Pavlyk
+* Peter Andreas Entschev
+* Sergei Lebedev
+* Seth Troisi +
+* Vladimir Pershin +
+* Warren Weckesser
+
+
+Pull requests merged
+====================
+
+A total of 24 pull requests were merged for this release.
+
+* `#14156 <https://github.com/numpy/numpy/pull/14156>`__: TST: Allow fuss in testing strided/non-strided exp/log loops
+* `#14157 <https://github.com/numpy/numpy/pull/14157>`__: BUG: avx2_scalef_ps must be static
+* `#14158 <https://github.com/numpy/numpy/pull/14158>`__: BUG: Remove stray print that causes a SystemError on python 3.7.
+* `#14159 <https://github.com/numpy/numpy/pull/14159>`__: BUG: Fix DeprecationWarning in python 3.8.
+* `#14160 <https://github.com/numpy/numpy/pull/14160>`__: BLD: Add missing gcd/lcm definitions to npy_math.h
+* `#14161 <https://github.com/numpy/numpy/pull/14161>`__: DOC, BUILD: cleanups and fix (again) 'build dist'
+* `#14166 <https://github.com/numpy/numpy/pull/14166>`__: TST: Add 3.8-dev to travisCI testing.
+* `#14194 <https://github.com/numpy/numpy/pull/14194>`__: BUG: Remove the broken clip wrapper (Backport)
+* `#14198 <https://github.com/numpy/numpy/pull/14198>`__: DOC: Fix hermitian argument docs in svd.
+* `#14199 <https://github.com/numpy/numpy/pull/14199>`__: MAINT: Workaround for Intel compiler bug leading to failing test
+* `#14200 <https://github.com/numpy/numpy/pull/14200>`__: TST: Clean up of test_pocketfft.py
+* `#14201 <https://github.com/numpy/numpy/pull/14201>`__: BUG: Make advanced indexing result on read-only subclass writeable...
+* `#14236 <https://github.com/numpy/numpy/pull/14236>`__: BUG: Fixed default BitGenerator name
+* `#14237 <https://github.com/numpy/numpy/pull/14237>`__: ENH: add c-imported modules for freeze analysis in np.random
+* `#14296 <https://github.com/numpy/numpy/pull/14296>`__: TST: Pin pytest version to 5.0.1
+* `#14301 <https://github.com/numpy/numpy/pull/14301>`__: BUG: Fix leak in the f2py-generated module init and `PyMem_Del`...
+* `#14302 <https://github.com/numpy/numpy/pull/14302>`__: BUG: Fix formatting error in exception message
+* `#14307 <https://github.com/numpy/numpy/pull/14307>`__: MAINT: random: Match type of SeedSequence.pool_size to DEFAULT_POOL_SIZE.
+* `#14308 <https://github.com/numpy/numpy/pull/14308>`__: BUG: Fix numpy.random bug in platform detection
+* `#14309 <https://github.com/numpy/numpy/pull/14309>`__: ENH: Enable huge pages in all Linux builds
+* `#14330 <https://github.com/numpy/numpy/pull/14330>`__: BUG: Fix segfault in `random.permutation(x)` when x is a string.
+* `#14338 <https://github.com/numpy/numpy/pull/14338>`__: BUG: don't fail when lexsorting some empty arrays (#14228)
+* `#14339 <https://github.com/numpy/numpy/pull/14339>`__: BUG: Fix misuse of .names and .fields in various places (backport...
+* `#14345 <https://github.com/numpy/numpy/pull/14345>`__: BUG: fix behavior of structured_to_unstructured on non-trivial...
+* `#14350 <https://github.com/numpy/numpy/pull/14350>`__: REL: Prepare 1.17.1 release
Release Notes
*************
+.. include:: ../release/1.17.1-notes.rst
.. include:: ../release/1.17.0-notes.rst
.. include:: ../release/1.16.4-notes.rst
.. include:: ../release/1.16.3-notes.rst
if newtype.hasobject or oldtype.hasobject:
if offset == 0 and newtype == oldtype:
return
- if oldtype.names:
+ if oldtype.names is not None:
for name in oldtype.names:
if (oldtype.fields[name][1] == offset and
oldtype.fields[name][0] == newtype):
if style is np._NoValue:
style = repr
- if a.shape == () and not a.dtype.names:
+ 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
#define NPY_SQRT2l 1.414213562373095048801688724209698079L /* sqrt(2) */
#define NPY_SQRT1_2l 0.707106781186547524400844362104849039L /* 1/sqrt(2) */
-/*
- * Constants used in vector implementation of exp(x)
+/*
+ * Constants used in vector implementation of exp(x)
*/
#define NPY_RINT_CVT_MAGICf 0x1.800000p+23f
#define NPY_CODY_WAITE_LOGE_2_HIGHf -6.93145752e-1f
#define NPY_CODY_WAITE_LOGE_2_LOWf -1.42860677e-6f
-#define NPY_COEFF_P0_EXPf 9.999999999980870924916e-01f
-#define NPY_COEFF_P1_EXPf 7.257664613233124478488e-01f
-#define NPY_COEFF_P2_EXPf 2.473615434895520810817e-01f
-#define NPY_COEFF_P3_EXPf 5.114512081637298353406e-02f
-#define NPY_COEFF_P4_EXPf 6.757896990527504603057e-03f
-#define NPY_COEFF_P5_EXPf 5.082762527590693718096e-04f
-#define NPY_COEFF_Q0_EXPf 1.000000000000000000000e+00f
-#define NPY_COEFF_Q1_EXPf -2.742335390411667452936e-01f
-#define NPY_COEFF_Q2_EXPf 2.159509375685829852307e-02f
-
-/*
- * Constants used in vector implementation of log(x)
+#define NPY_COEFF_P0_EXPf 9.999999999980870924916e-01f
+#define NPY_COEFF_P1_EXPf 7.257664613233124478488e-01f
+#define NPY_COEFF_P2_EXPf 2.473615434895520810817e-01f
+#define NPY_COEFF_P3_EXPf 5.114512081637298353406e-02f
+#define NPY_COEFF_P4_EXPf 6.757896990527504603057e-03f
+#define NPY_COEFF_P5_EXPf 5.082762527590693718096e-04f
+#define NPY_COEFF_Q0_EXPf 1.000000000000000000000e+00f
+#define NPY_COEFF_Q1_EXPf -2.742335390411667452936e-01f
+#define NPY_COEFF_Q2_EXPf 2.159509375685829852307e-02f
+
+/*
+ * Constants used in vector implementation of log(x)
+ */
+#define NPY_COEFF_P0_LOGf 0.000000000000000000000e+00f
+#define NPY_COEFF_P1_LOGf 9.999999999999998702752e-01f
+#define NPY_COEFF_P2_LOGf 2.112677543073053063722e+00f
+#define NPY_COEFF_P3_LOGf 1.480000633576506585156e+00f
+#define NPY_COEFF_P4_LOGf 3.808837741388407920751e-01f
+#define NPY_COEFF_P5_LOGf 2.589979117907922693523e-02f
+#define NPY_COEFF_Q0_LOGf 1.000000000000000000000e+00f
+#define NPY_COEFF_Q1_LOGf 2.612677543073109236779e+00f
+#define NPY_COEFF_Q2_LOGf 2.453006071784736363091e+00f
+#define NPY_COEFF_Q3_LOGf 9.864942958519418960339e-01f
+#define NPY_COEFF_Q4_LOGf 1.546476374983906719538e-01f
+#define NPY_COEFF_Q5_LOGf 5.875095403124574342950e-03f
+
+/*
+ * Integer functions.
*/
-#define NPY_COEFF_P0_LOGf 0.000000000000000000000e+00f
-#define NPY_COEFF_P1_LOGf 9.999999999999998702752e-01f
-#define NPY_COEFF_P2_LOGf 2.112677543073053063722e+00f
-#define NPY_COEFF_P3_LOGf 1.480000633576506585156e+00f
-#define NPY_COEFF_P4_LOGf 3.808837741388407920751e-01f
-#define NPY_COEFF_P5_LOGf 2.589979117907922693523e-02f
-#define NPY_COEFF_Q0_LOGf 1.000000000000000000000e+00f
-#define NPY_COEFF_Q1_LOGf 2.612677543073109236779e+00f
-#define NPY_COEFF_Q2_LOGf 2.453006071784736363091e+00f
-#define NPY_COEFF_Q3_LOGf 9.864942958519418960339e-01f
-#define NPY_COEFF_Q4_LOGf 1.546476374983906719538e-01f
-#define NPY_COEFF_Q5_LOGf 5.875095403124574342950e-03f
+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);
/*
* C99 double math funcs
except AttributeError:
#happens if field is Object type
return obj
- if dt.fields:
- return obj.view((self.__class__, obj.dtype.fields))
+ if dt.names is not None:
+ return obj.view((self.__class__, obj.dtype))
return obj
else:
raise AttributeError("'record' object has no "
obj = nt.void.__getitem__(self, indx)
# copy behavior of record.__getattribute__,
- if isinstance(obj, nt.void) and obj.dtype.fields:
- return obj.view((self.__class__, obj.dtype.fields))
+ if isinstance(obj, nt.void) and obj.dtype.names is not None:
+ return obj.view((self.__class__, obj.dtype))
else:
# return a single element
return obj
return self
def __array_finalize__(self, obj):
- if self.dtype.type is not record and self.dtype.fields:
+ if self.dtype.type is not record and self.dtype.names is not None:
# if self.dtype is not np.record, invoke __setattr__ which will
# convert it to a record if it is a void dtype.
self.dtype = self.dtype
# with void type convert it to the same dtype.type (eg to preserve
# numpy.record type if present), since nested structured fields do not
# inherit type. Don't do this for non-void structures though.
- if obj.dtype.fields:
+ if obj.dtype.names is not None:
if issubclass(obj.dtype.type, nt.void):
return obj.view(dtype=(self.dtype.type, obj.dtype))
return obj
# Automatically convert (void) structured types to records
# (but not non-void structures, subarrays, or non-structured voids)
- if attr == 'dtype' and issubclass(val.type, nt.void) and val.fields:
+ if attr == 'dtype' and issubclass(val.type, nt.void) and val.names is not None:
val = sb.dtype((record, val))
newattr = attr not in self.__dict__
# copy behavior of getattr, except that here
# we might also be returning a single element
if isinstance(obj, ndarray):
- if obj.dtype.fields:
+ if obj.dtype.names is not None:
obj = obj.view(type(self))
if issubclass(obj.dtype.type, nt.void):
return obj.view(dtype=(self.dtype.type, obj.dtype))
if val is None:
obj = self.getfield(*res)
- if obj.dtype.fields:
+ if obj.dtype.names is not None:
return obj
return obj.view(ndarray)
else:
#include <assert.h>
-#ifdef HAVE_SYS_MMAN_H
+#ifdef NPY_OS_LINUX
#include <sys/mman.h>
-#if defined MADV_HUGEPAGE && defined HAVE_MADVISE
-#define HAVE_MADV_HUGEPAGE
+#ifndef MADV_HUGEPAGE
+/*
+ * Use code 14 (MADV_HUGEPAGE) if it isn't defined. This gives a chance of
+ * enabling huge pages even if built with linux kernel < 2.6.38
+ */
+#define MADV_HUGEPAGE 14
#endif
#endif
#ifdef _PyPyGC_AddMemoryPressure
_PyPyPyGC_AddMemoryPressure(nelem * esz);
#endif
-#ifdef HAVE_MADV_HUGEPAGE
+#ifdef NPY_OS_LINUX
/* allow kernel allocating huge pages for large arrays */
if (NPY_UNLIKELY(nelem * esz >= ((1u<<22u)))) {
npy_uintp offset = 4096u - (npy_uintp)p % (4096u);
npy_uintp length = nelem * esz - offset;
+ /**
+ * Intentionally not checking for errors that may be returned by
+ * older kernel versions; optimistically tries enabling huge pages.
+ */
madvise((void*)((npy_uintp)p + offset), length, MADV_HUGEPAGE);
}
#endif
#define LIKELY_IN_CACHE_SIZE 8
+#ifdef __INTEL_COMPILER
+#pragma intel optimization_level 0
+#endif
+static NPY_INLINE npy_intp
+_linear_search(const npy_double key, const npy_double *arr, const npy_intp len, const npy_intp i0)
+{
+ npy_intp i;
+
+ for (i = i0; i < len && key >= arr[i]; i++);
+ return i - 1;
+}
+
/** @brief find index of a sorted array such that arr[i] <= key < arr[i + 1].
*
* If an starting index guess is in-range, the array values around this
* From above we know key >= arr[0] when we start.
*/
if (len <= 4) {
- npy_intp i;
-
- for (i = 1; i < len && key >= arr[i]; ++i);
- return i - 1;
+ return _linear_search(key, arr, len, 1);
}
if (guess > len - 3) {
if (tmp == NULL) {
return -1;
}
- seconds_offset = PyInt_AsLong(tmp);
+ /* Rounding here is no worse than the integer division below.
+ * Only whole minute offsets are supported by numpy anyway.
+ */
+ seconds_offset = (int)PyFloat_AsDouble(tmp);
if (error_converting(seconds_offset)) {
Py_DECREF(tmp);
return -1;
else {
ret = PyArray_DescrConverter(PyTuple_GET_ITEM(item, 1), &conv);
}
- if (ret == NPY_FAIL) {
- PyObject_Print(PyTuple_GET_ITEM(item, 1), stderr, 0);
- }
}
else if (PyTuple_GET_SIZE(item) == 3) {
newobj = PyTuple_GetSlice(item, 1, 3);
if (ret == NPY_FAIL) {
goto fail;
}
+
if ((PyDict_GetItem(fields, name) != NULL)
|| (title
&& PyBaseString_Check(title)
/* Now we can check the axis */
nd = PyArray_NDIM(mps[0]);
- if ((nd == 0) || (PyArray_SIZE(mps[0]) == 1)) {
- /* single element case */
+ if ((nd == 0) || (PyArray_SIZE(mps[0]) <= 1)) {
+ /* empty/single element case */
ret = (PyArrayObject *)PyArray_NewFromDescr(
&PyArray_Type, PyArray_DescrFromType(NPY_INTP),
PyArray_NDIM(mps[0]), PyArray_DIMS(mps[0]), NULL, NULL,
if (ret == NULL) {
goto fail;
}
- *((npy_intp *)(PyArray_DATA(ret))) = 0;
+ if (PyArray_SIZE(mps[0]) > 0) {
+ *((npy_intp *)(PyArray_DATA(ret))) = 0;
+ }
goto finish;
}
if (check_and_adjust_axis(&axis, nd) < 0) {
char *valbuffer, *indbuffer;
int *swaps;
- if (N == 0 || maxelsize == 0 || sizeof(npy_intp) == 0) {
- goto fail;
+ assert(N > 0); /* Guaranteed and assumed by indbuffer */
+ int valbufsize = N * maxelsize;
+ if (NPY_UNLIKELY(valbufsize) == 0) {
+ valbufsize = 1; /* Ensure allocation is not empty */
}
- valbuffer = PyDataMem_NEW(N * maxelsize);
+
+ valbuffer = PyDataMem_NEW(valbufsize);
if (valbuffer == NULL) {
goto fail;
}
indbuffer = PyDataMem_NEW(N * sizeof(npy_intp));
if (indbuffer == NULL) {
+ PyDataMem_FREE(valbuffer);
+ goto fail;
+ }
+ swaps = malloc(NPY_LIKELY(n > 0) ? n * sizeof(int) : 1);
+ if (swaps == NULL) {
+ PyDataMem_FREE(valbuffer);
PyDataMem_FREE(indbuffer);
goto fail;
}
- swaps = malloc(n*sizeof(int));
+
for (j = 0; j < n; j++) {
swaps[j] = PyArray_ISBYTESWAPPED(mps[j]);
}
#else
if (rcode < 0) {
#endif
- npy_free_cache(valbuffer, N * maxelsize);
- npy_free_cache(indbuffer, N * sizeof(npy_intp));
+ PyDataMem_FREE(valbuffer);
+ PyDataMem_FREE(indbuffer);
free(swaps);
goto fail;
}
PyArray_SHAPE(tmp_arr),
PyArray_STRIDES(tmp_arr),
PyArray_BYTES(tmp_arr),
- PyArray_FLAGS(self),
+ PyArray_FLAGS(tmp_arr),
(PyObject *)self, (PyObject *)tmp_arr);
Py_DECREF(tmp_arr);
if (result == NULL) {
_mm256_castps_si256(x), mantissa_bits), exp_126_bits));
}
-NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX2 __m256
+static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX2 __m256
avx2_scalef_ps(__m256 poly, __m256 quadrant)
{
/*
(self.warning_cls.__name__, warning.category))
if num is not None and num_found != num:
msg = "%i warnings found but %i expected." % (len(self.log), num)
- lst = [str(w.category) for w in self.log]
+ lst = [str(w) for w in self.log]
raise AssertionError("\n".join([msg] + lst))
with warnings.catch_warnings():
assert_array_equal(s_bool, a[a > 0])
assert_array_equal(s_bool.base, a[a > 0])
+ def test_fancy_on_read_only(self):
+ # Test that fancy indexing on read-only SubClass does not make a
+ # read-only copy (gh-14132)
+ class SubClass(np.ndarray):
+ pass
+
+ a = np.arange(5)
+ s = a.view(SubClass)
+ s.flags.writeable = False
+ s_fancy = s[[0, 1, 2]]
+ assert_(s_fancy.flags.writeable)
+
+
def test_finalize_gets_full_info(self):
# Array finalize should be called on the filled array.
class SubClass(np.ndarray):
]
arr = np.rec.fromarrays(arrays) # ValueError?
+ @pytest.mark.parametrize('nfields', [0, 1, 2])
+ def test_assign_dtype_attribute(self, nfields):
+ dt = np.dtype([('a', np.uint8), ('b', np.uint8), ('c', np.uint8)][:nfields])
+ data = np.zeros(3, dt).view(np.recarray)
+
+ # the original and resulting dtypes differ on whether they are records
+ assert data.dtype.type == np.record
+ assert dt.type != np.record
+
+ # ensure that the dtype remains a record even when assigned
+ data.dtype = dt
+ assert data.dtype.type == np.record
+
+ @pytest.mark.parametrize('nfields', [0, 1, 2])
+ def test_nested_fields_are_records(self, nfields):
+ """ Test that nested structured types are treated as records too """
+ dt = np.dtype([('a', np.uint8), ('b', np.uint8), ('c', np.uint8)][:nfields])
+ dt_outer = np.dtype([('inner', dt)])
+
+ data = np.zeros(3, dt_outer).view(np.recarray)
+ assert isinstance(data, np.recarray)
+ assert isinstance(data['inner'], np.recarray)
+
+ data0 = data[0]
+ assert isinstance(data0, np.record)
+ assert isinstance(data0['inner'], np.record)
+
+ def test_nested_dtype_padding(self):
+ """ test that trailing padding is preserved """
+ # construct a dtype with padding at the end
+ dt = np.dtype([('a', np.uint8), ('b', np.uint8), ('c', np.uint8)])
+ dt_padded_end = dt[['a', 'b']]
+ assert dt_padded_end.itemsize == dt.itemsize
+
+ dt_outer = np.dtype([('inner', dt_padded_end)])
+
+ data = np.zeros(3, dt_outer).view(np.recarray)
+ assert_equal(data['inner'].dtype, dt_padded_end)
+
+ data0 = data[0]
+ assert_equal(data0['inner'].dtype, dt_padded_end)
+
def test_find_duplicate():
l1 = [1, 2, 3, 4, 5, 6]
assert_raises(KeyError, np.lexsort, BuggySequence())
+ def test_lexsort_zerolen_custom_strides(self):
+ # Ticket #14228
+ xs = np.array([], dtype='i8')
+ assert xs.strides == (8,)
+ assert np.lexsort((xs,)).shape[0] == 0 # Works
+
+ xs.strides = (16,)
+ assert np.lexsort((xs,)).shape[0] == 0 # Was: MemoryError
+
+ def test_lexsort_zerolen_custom_strides_2d(self):
+ xs = np.array([], dtype='i8')
+
+ xs.shape = (0, 2)
+ xs.strides = (16, 16)
+ assert np.lexsort((xs,), axis=0).shape[0] == 0
+
+ xs.shape = (2, 0)
+ xs.strides = (16, 16)
+ assert np.lexsort((xs,), axis=0).shape[0] == 2
+
+ def test_lexsort_zerolen_element(self):
+ dt = np.dtype([]) # a void dtype with no fields
+ xs = np.empty(4, dt)
+
+ assert np.lexsort((xs,)).shape[0] == xs.shape[0]
+
def test_pickle_py2_bytes_encoding(self):
# Check that arrays and scalars pickled on Py2 are
# unpickleable on Py3 using encoding='bytes'
result = pickle.loads(data, encoding='bytes')
assert_equal(result, original)
- if isinstance(result, np.ndarray) and result.dtype.names:
+ if isinstance(result, np.ndarray) and result.dtype.names is not None:
for name in result.dtype.names:
assert_(isinstance(name, str))
assert_, assert_equal, assert_raises, assert_raises_regex,
assert_array_equal, assert_almost_equal, assert_array_almost_equal,
assert_array_max_ulp, assert_allclose, assert_no_warnings, suppress_warnings,
- _gen_alignment_data
+ _gen_alignment_data, assert_array_almost_equal_nulp
)
def on_powerpc():
exp_true = np.exp(x_f32)
log_true = np.log(x_f32)
for jj in strides:
- assert_equal(np.exp(x_f32[::jj]), exp_true[::jj])
- assert_equal(np.log(x_f32[::jj]), log_true[::jj])
+ assert_array_almost_equal_nulp(np.exp(x_f32[::jj]), exp_true[::jj], nulp=2)
+ assert_array_almost_equal_nulp(np.log(x_f32[::jj]), log_true[::jj], nulp=2)
class TestLogAddExp(_FilterInvalids):
def test_logaddexp_values(self):
# produce a name for the new type
if dtype is None:
name = 'any'
- elif dtype.names:
+ elif dtype.names is not None:
name = str(id(dtype))
else:
name = dtype.str
PyMODINIT_FUNC init#modulename#(void) {
#endif
\tint i;
-\tPyObject *m,*d, *s;
+\tPyObject *m,*d, *s, *tmp;
#if PY_VERSION_HEX >= 0x03000000
\tm = #modulename#_module = PyModule_Create(&moduledef);
#else
\tPyDict_SetItemString(d, \"__doc__\", s);
\t#modulename#_error = PyErr_NewException (\"#modulename#.error\", NULL, NULL);
\tPy_DECREF(s);
-\tfor(i=0;f2py_routine_defs[i].name!=NULL;i++)
-\t\tPyDict_SetItemString(d, f2py_routine_defs[i].name,PyFortranObject_NewAsAttr(&f2py_routine_defs[i]));
+\tfor(i=0;f2py_routine_defs[i].name!=NULL;i++) {
+\t\ttmp = PyFortranObject_NewAsAttr(&f2py_routine_defs[i]);
+\t\tPyDict_SetItemString(d, f2py_routine_defs[i].name, tmp);
+\t\tPy_DECREF(tmp);
+\t}
#initf2pywraphooks#
#initf90modhooks#
#initcommonhooks#
PyFortranObject *fp = NULL;
fp = PyObject_New(PyFortranObject, &PyFortran_Type);
if (fp == NULL) return NULL;
- if ((fp->dict = PyDict_New())==NULL) return NULL;
+ if ((fp->dict = PyDict_New())==NULL) {
+ PyObject_Del(fp);
+ return NULL;
+ }
fp->len = 1;
fp->defs = defs;
return (PyObject *)fp;
static void
fortran_dealloc(PyFortranObject *fp) {
Py_XDECREF(fp->dict);
- PyMem_Del(fp);
+ PyObject_Del(fp);
}
import pytest
from numpy.random import random
from numpy.testing import (
- assert_array_almost_equal, assert_array_equal, assert_raises,
+ assert_array_equal, assert_raises, assert_allclose
)
import threading
import sys
x = random(maxlen) + 1j*random(maxlen)
xr = random(maxlen)
for i in range(1,maxlen):
- assert_array_almost_equal(np.fft.ifft(np.fft.fft(x[0:i])), x[0:i],
- decimal=12)
- assert_array_almost_equal(np.fft.irfft(np.fft.rfft(xr[0:i]),i),
- xr[0:i], decimal=12)
+ assert_allclose(np.fft.ifft(np.fft.fft(x[0:i])), x[0:i],
+ atol=1e-12)
+ assert_allclose(np.fft.irfft(np.fft.rfft(xr[0:i]),i),
+ xr[0:i], atol=1e-12)
def test_fft(self):
x = random(30) + 1j*random(30)
- assert_array_almost_equal(fft1(x), np.fft.fft(x))
- assert_array_almost_equal(fft1(x) / np.sqrt(30),
- np.fft.fft(x, norm="ortho"))
+ assert_allclose(fft1(x), np.fft.fft(x), atol=1e-6)
+ assert_allclose(fft1(x) / np.sqrt(30),
+ np.fft.fft(x, norm="ortho"), atol=1e-6)
def test_ifft(self):
x = random(30) + 1j*random(30)
- assert_array_almost_equal(x, np.fft.ifft(np.fft.fft(x)))
- assert_array_almost_equal(
- x, np.fft.ifft(np.fft.fft(x, norm="ortho"), norm="ortho"))
+ assert_allclose(x, np.fft.ifft(np.fft.fft(x)), atol=1e-6)
+ assert_allclose(
+ x, np.fft.ifft(np.fft.fft(x, norm="ortho"), norm="ortho"),
+ atol=1e-6)
def test_fft2(self):
x = random((30, 20)) + 1j*random((30, 20))
- assert_array_almost_equal(np.fft.fft(np.fft.fft(x, axis=1), axis=0),
- np.fft.fft2(x))
- assert_array_almost_equal(np.fft.fft2(x) / np.sqrt(30 * 20),
- np.fft.fft2(x, norm="ortho"))
+ assert_allclose(np.fft.fft(np.fft.fft(x, axis=1), axis=0),
+ np.fft.fft2(x), atol=1e-6)
+ assert_allclose(np.fft.fft2(x) / np.sqrt(30 * 20),
+ np.fft.fft2(x, norm="ortho"), atol=1e-6)
def test_ifft2(self):
x = random((30, 20)) + 1j*random((30, 20))
- assert_array_almost_equal(np.fft.ifft(np.fft.ifft(x, axis=1), axis=0),
- np.fft.ifft2(x))
- assert_array_almost_equal(np.fft.ifft2(x) * np.sqrt(30 * 20),
- np.fft.ifft2(x, norm="ortho"))
+ assert_allclose(np.fft.ifft(np.fft.ifft(x, axis=1), axis=0),
+ np.fft.ifft2(x), atol=1e-6)
+ assert_allclose(np.fft.ifft2(x) * np.sqrt(30 * 20),
+ np.fft.ifft2(x, norm="ortho"), atol=1e-6)
def test_fftn(self):
x = random((30, 20, 10)) + 1j*random((30, 20, 10))
- assert_array_almost_equal(
+ assert_allclose(
np.fft.fft(np.fft.fft(np.fft.fft(x, axis=2), axis=1), axis=0),
- np.fft.fftn(x))
- assert_array_almost_equal(np.fft.fftn(x) / np.sqrt(30 * 20 * 10),
- np.fft.fftn(x, norm="ortho"))
+ np.fft.fftn(x), atol=1e-6)
+ assert_allclose(np.fft.fftn(x) / np.sqrt(30 * 20 * 10),
+ np.fft.fftn(x, norm="ortho"), atol=1e-6)
def test_ifftn(self):
x = random((30, 20, 10)) + 1j*random((30, 20, 10))
- assert_array_almost_equal(
+ assert_allclose(
np.fft.ifft(np.fft.ifft(np.fft.ifft(x, axis=2), axis=1), axis=0),
- np.fft.ifftn(x))
- assert_array_almost_equal(np.fft.ifftn(x) * np.sqrt(30 * 20 * 10),
- np.fft.ifftn(x, norm="ortho"))
+ np.fft.ifftn(x), atol=1e-6)
+ assert_allclose(np.fft.ifftn(x) * np.sqrt(30 * 20 * 10),
+ np.fft.ifftn(x, norm="ortho"), atol=1e-6)
def test_rfft(self):
x = random(30)
for n in [x.size, 2*x.size]:
for norm in [None, 'ortho']:
- assert_array_almost_equal(
+ assert_allclose(
np.fft.fft(x, n=n, norm=norm)[:(n//2 + 1)],
- np.fft.rfft(x, n=n, norm=norm))
- assert_array_almost_equal(np.fft.rfft(x, n=n) / np.sqrt(n),
- np.fft.rfft(x, n=n, norm="ortho"))
+ np.fft.rfft(x, n=n, norm=norm), atol=1e-6)
+ assert_allclose(
+ np.fft.rfft(x, n=n) / np.sqrt(n),
+ np.fft.rfft(x, n=n, norm="ortho"), atol=1e-6)
def test_irfft(self):
x = random(30)
- assert_array_almost_equal(x, np.fft.irfft(np.fft.rfft(x)))
- assert_array_almost_equal(
- x, np.fft.irfft(np.fft.rfft(x, norm="ortho"), norm="ortho"))
+ assert_allclose(x, np.fft.irfft(np.fft.rfft(x)), atol=1e-6)
+ assert_allclose(
+ x, np.fft.irfft(np.fft.rfft(x, norm="ortho"), norm="ortho"), atol=1e-6)
def test_rfft2(self):
x = random((30, 20))
- assert_array_almost_equal(np.fft.fft2(x)[:, :11], np.fft.rfft2(x))
- assert_array_almost_equal(np.fft.rfft2(x) / np.sqrt(30 * 20),
- np.fft.rfft2(x, norm="ortho"))
+ assert_allclose(np.fft.fft2(x)[:, :11], np.fft.rfft2(x), atol=1e-6)
+ assert_allclose(np.fft.rfft2(x) / np.sqrt(30 * 20),
+ np.fft.rfft2(x, norm="ortho"), atol=1e-6)
def test_irfft2(self):
x = random((30, 20))
- assert_array_almost_equal(x, np.fft.irfft2(np.fft.rfft2(x)))
- assert_array_almost_equal(
- x, np.fft.irfft2(np.fft.rfft2(x, norm="ortho"), norm="ortho"))
+ assert_allclose(x, np.fft.irfft2(np.fft.rfft2(x)), atol=1e-6)
+ assert_allclose(
+ x, np.fft.irfft2(np.fft.rfft2(x, norm="ortho"), norm="ortho"), atol=1e-6)
def test_rfftn(self):
x = random((30, 20, 10))
- assert_array_almost_equal(np.fft.fftn(x)[:, :, :6], np.fft.rfftn(x))
- assert_array_almost_equal(np.fft.rfftn(x) / np.sqrt(30 * 20 * 10),
- np.fft.rfftn(x, norm="ortho"))
+ assert_allclose(np.fft.fftn(x)[:, :, :6], np.fft.rfftn(x), atol=1e-6)
+ assert_allclose(np.fft.rfftn(x) / np.sqrt(30 * 20 * 10),
+ np.fft.rfftn(x, norm="ortho"), atol=1e-6)
def test_irfftn(self):
x = random((30, 20, 10))
- assert_array_almost_equal(x, np.fft.irfftn(np.fft.rfftn(x)))
- assert_array_almost_equal(
- x, np.fft.irfftn(np.fft.rfftn(x, norm="ortho"), norm="ortho"))
+ assert_allclose(x, np.fft.irfftn(np.fft.rfftn(x)), atol=1e-6)
+ assert_allclose(
+ x, np.fft.irfftn(np.fft.rfftn(x, norm="ortho"), norm="ortho"), atol=1e-6)
def test_hfft(self):
x = random(14) + 1j*random(14)
x_herm = np.concatenate((random(1), x, random(1)))
x = np.concatenate((x_herm, x[::-1].conj()))
- assert_array_almost_equal(np.fft.fft(x), np.fft.hfft(x_herm))
- assert_array_almost_equal(np.fft.hfft(x_herm) / np.sqrt(30),
- np.fft.hfft(x_herm, norm="ortho"))
+ assert_allclose(np.fft.fft(x), np.fft.hfft(x_herm), atol=1e-6)
+ assert_allclose(np.fft.hfft(x_herm) / np.sqrt(30),
+ np.fft.hfft(x_herm, norm="ortho"), atol=1e-6)
def test_ihttf(self):
x = random(14) + 1j*random(14)
x_herm = np.concatenate((random(1), x, random(1)))
x = np.concatenate((x_herm, x[::-1].conj()))
- assert_array_almost_equal(x_herm, np.fft.ihfft(np.fft.hfft(x_herm)))
- assert_array_almost_equal(
+ assert_allclose(x_herm, np.fft.ihfft(np.fft.hfft(x_herm)), atol=1e-6)
+ assert_allclose(
x_herm, np.fft.ihfft(np.fft.hfft(x_herm, norm="ortho"),
- norm="ortho"))
+ norm="ortho"), atol=1e-6)
@pytest.mark.parametrize("op", [np.fft.fftn, np.fft.ifftn,
np.fft.rfftn, np.fft.irfftn])
for a in axes:
op_tr = op(np.transpose(x, a))
tr_op = np.transpose(op(x, axes=a), a)
- assert_array_almost_equal(op_tr, tr_op)
+ assert_allclose(op_tr, tr_op, atol=1e-6)
def test_all_1d_norm_preserving(self):
# verify that round-trip transforms are norm-preserving
for norm in [None, 'ortho']:
tmp = forw(x, n=n, norm=norm)
tmp = back(tmp, n=n, norm=norm)
- assert_array_almost_equal(x_norm,
- np.linalg.norm(tmp))
+ assert_allclose(x_norm,
+ np.linalg.norm(tmp), atol=1e-6)
@pytest.mark.parametrize("dtype", [np.half, np.single, np.double,
np.longdouble])
# make sure that all input precisions are accepted and internally
# converted to 64bit
x = random(30).astype(dtype)
- assert_array_almost_equal(np.fft.ifft(np.fft.fft(x)), x)
- assert_array_almost_equal(np.fft.irfft(np.fft.rfft(x)), x)
+ assert_allclose(np.fft.ifft(np.fft.fft(x)), x, atol=1e-6)
+ assert_allclose(np.fft.irfft(np.fft.rfft(x)), x, atol=1e-6)
@pytest.mark.parametrize(
# non contiguous arrays
rng = np.random.RandomState(42)
X = rng.rand(8, 7, 13).astype(dtype, copy=False)
+ # See discussion in pull/14178
+ _tol = 8.0 * np.sqrt(np.log2(X.size)) * np.finfo(X.dtype).eps
if order == 'F':
Y = np.asfortranarray(X)
else:
for axis in range(3):
X_res = fft(X, axis=axis)
Y_res = fft(Y, axis=axis)
- assert_array_almost_equal(X_res, Y_res)
+ assert_allclose(X_res, Y_res, atol=_tol, rtol=_tol)
elif fft.__name__.endswith(('fft2', 'fftn')):
axes = [(0, 1), (1, 2), (0, 2)]
if fft.__name__.endswith('fftn'):
for ax in axes:
X_res = fft(X, axes=ax)
Y_res = fft(Y, axes=ax)
- assert_array_almost_equal(X_res, Y_res)
+ assert_allclose(X_res, Y_res, atol=_tol, rtol=_tol)
else:
- raise ValueError
+ raise ValueError()
class TestFFTThreadSafe(object):
"""
for name in ndtype.names or ():
- if ndtype[name].names:
+ if ndtype[name].names is not None:
return True
return False
names = validate(names, nbfields=nbfields, defaultfmt=defaultfmt)
ndtype = np.dtype(dict(formats=ndtype, names=names))
else:
- nbtypes = len(ndtype)
# Explicit names
if names is not None:
validate = NameValidator(**validationargs)
if isinstance(names, basestring):
names = names.split(",")
# Simple dtype: repeat to match the nb of names
- if nbtypes == 0:
+ if ndtype.names is None:
formats = tuple([ndtype.type] * len(names))
names = validate(names, defaultfmt=defaultfmt)
ndtype = np.dtype(list(zip(names, formats)))
# Structured dtype: just validate the names as needed
else:
- ndtype.names = validate(names, nbfields=nbtypes,
+ ndtype.names = validate(names, nbfields=len(ndtype.names),
defaultfmt=defaultfmt)
# No implicit names
- elif (nbtypes > 0):
+ elif ndtype.names is not None:
validate = NameValidator(**validationargs)
# Default initial names : should we change the format ?
- if ((ndtype.names == tuple("f%i" % i for i in range(nbtypes))) and
+ if ((ndtype.names == tuple("f%i" % i for i in range(len(ndtype.names)))) and
(defaultfmt != "f%i")):
- ndtype.names = validate([''] * nbtypes, defaultfmt=defaultfmt)
+ ndtype.names = validate([''] * len(ndtype.names), defaultfmt=defaultfmt)
# Explicit initial names : just validate
else:
ndtype.names = validate(ndtype.names, defaultfmt=defaultfmt)
outputmask = np.array(masks, dtype=mdtype)
else:
# Overwrite the initial dtype names if needed
- if names and dtype.names:
+ if names and dtype.names is not None:
dtype.names = names
# Case 1. We have a structured type
if len(dtype_flat) > 1:
#
output = np.array(data, dtype)
if usemask:
- if dtype.names:
+ if dtype.names is not None:
mdtype = [(_, bool) for _ in dtype.names]
else:
mdtype = bool
current = input[field]
except ValueError:
continue
- if current.dtype.names:
+ if current.dtype.names is not None:
recursive_fill_fields(current, output[field])
else:
output[field][:len(current)] = current
names = adtype.names
for name in names:
current = adtype[name]
- if current.names:
+ if current.names is not None:
listnames.append((name, tuple(get_names(current))))
else:
listnames.append(name)
- return tuple(listnames) or None
+ return tuple(listnames)
def get_names_flat(adtype):
for name in names:
listnames.append(name)
current = adtype[name]
- if current.names:
+ if current.names is not None:
listnames.extend(get_names_flat(current))
- return tuple(listnames) or None
+ return tuple(listnames)
def flatten_descr(ndtype):
else:
for a in seqarrays:
current = a.dtype
- if current.names and len(current.names) <= 1:
- # special case - dtypes of 0 or 1 field are flattened
+ if current.names is not None and len(current.names) == 1:
+ # special case - dtypes of 1 field are flattened
newdtype.extend(_get_fieldspec(current))
else:
newdtype.append(('', current))
names = adtype.names
for name in names:
current = adtype[name]
- if current.names:
+ if current.names is not None:
if lastname:
parents[name] = [lastname, ]
else:
elif lastname:
lastparent = [lastname, ]
parents[name] = lastparent or []
- return parents or None
+ return parents
def _izip_fields_flat(iterable):
if isinstance(seqarrays, (ndarray, np.void)):
seqdtype = seqarrays.dtype
# Make sure we have named fields
- if not seqdtype.names:
+ if seqdtype.names is None:
seqdtype = np.dtype([('', seqdtype)])
if not flatten or _zip_dtype((seqarrays,), flatten=True) == seqdtype:
# Minimal processing needed: just make sure everythng's a-ok
for name in ndtype.names:
newname = namemapper.get(name, name)
current = ndtype[name]
- if current.names:
+ if current.names is not None:
newdtype.append(
(newname, _recursive_rename_fields(current, namemapper))
)
scalar fields in the dtype "dt", including nested fields, in left
to right order.
"""
+
+ # counts up elements in subarrays, including nested subarrays, and returns
+ # base dtype and count
+ def count_elem(dt):
+ count = 1
+ while dt.shape != ():
+ for size in dt.shape:
+ count *= size
+ dt = dt.base
+ return dt, count
+
fields = []
for name in dt.names:
field = dt.fields[name]
- if field[0].names is None:
- count = 1
- for size in field[0].shape:
- count *= size
- fields.append((field[0], count, field[1] + offset))
+ f_dt, f_offset = field[0], field[1]
+ f_dt, n = count_elem(f_dt)
+
+ if f_dt.names is None:
+ fields.append((np.dtype((f_dt, (n,))), n, f_offset + offset))
else:
- fields.extend(_get_fields_and_offsets(field[0], field[1] + offset))
+ subfields = _get_fields_and_offsets(f_dt, f_offset + offset)
+ size = f_dt.itemsize
+
+ for i in range(n):
+ if i == 0:
+ # optimization: avoid list comprehension if no subarray
+ fields.extend(subfields)
+ else:
+ fields.extend([(d, c, o + i*size) for d, c, o in subfields])
return fields
fields = _get_fields_and_offsets(arr.dtype)
n_fields = len(fields)
+ if n_fields == 0 and dtype is None:
+ raise ValueError("arr has no fields. Unable to guess dtype")
+ elif n_fields == 0:
+ # too many bugs elsewhere for this to work now
+ raise NotImplementedError("arr with no fields is not supported")
+
dts, counts, offsets = zip(*fields)
names = ['f{}'.format(n) for n in range(n_fields)]
if arr.shape == ():
raise ValueError('arr must have at least one dimension')
n_elem = arr.shape[-1]
+ if n_elem == 0:
+ # too many bugs elsewhere for this to work now
+ raise NotImplementedError("last axis with size 0 is not supported")
if dtype is None:
if names is None:
raise ValueError("don't supply both dtype and names")
# sanity check of the input dtype
fields = _get_fields_and_offsets(dtype)
- dts, counts, offsets = zip(*fields)
+ if len(fields) == 0:
+ dts, counts, offsets = [], [], []
+ else:
+ dts, counts, offsets = zip(*fields)
+
if n_elem != sum(counts):
raise ValueError('The length of the last dimension of arr must '
'be equal to the number of fields in dtype')
test = np.genfromtxt(TextIO(data), delimiter=";",
dtype=ndtype, converters=converters)
+ # nested but empty fields also aren't supported
+ ndtype = [('idx', int), ('code', object), ('nest', [])]
+ with assert_raises_regex(NotImplementedError,
+ 'Nested fields.* not supported.*'):
+ test = np.genfromtxt(TextIO(data), delimiter=";",
+ dtype=ndtype, converters=converters)
+
def test_userconverters_with_explicit_dtype(self):
# Test user_converters w/ explicit (standard) dtype
data = TextIO('skip,skip,2001-01-01,1.0,skip')
test = get_names(ndtype)
assert_equal(test, ('a', ('b', ('ba', 'bb'))))
+ ndtype = np.dtype([('a', int), ('b', [])])
+ test = get_names(ndtype)
+ assert_equal(test, ('a', ('b', ())))
+
+ ndtype = np.dtype([])
+ test = get_names(ndtype)
+ assert_equal(test, ())
+
def test_get_names_flat(self):
# Test get_names_flat
ndtype = np.dtype([('A', '|S3'), ('B', float)])
test = get_names_flat(ndtype)
assert_equal(test, ('a', 'b', 'ba', 'bb'))
+ ndtype = np.dtype([('a', int), ('b', [])])
+ test = get_names_flat(ndtype)
+ assert_equal(test, ('a', 'b'))
+
+ ndtype = np.dtype([])
+ test = get_names_flat(ndtype)
+ assert_equal(test, ())
+
def test_get_fieldstructure(self):
# Test get_fieldstructure
'BBA': ['B', 'BB'], 'BBB': ['B', 'BB']}
assert_equal(test, control)
+ # 0 fields
+ ndtype = np.dtype([])
+ test = get_fieldstructure(ndtype)
+ assert_equal(test, {})
+
def test_find_duplicates(self):
# Test find_duplicates
a = ma.array([(2, (2., 'B')), (1, (2., 'B')), (2, (2., 'B')),
# including uniform fields with subarrays unpacked
d = np.array([(1, [2, 3], [[ 4, 5], [ 6, 7]]),
(8, [9, 10], [[11, 12], [13, 14]])],
- dtype=[('x0', 'i4'), ('x1', ('i4', 2)), ('x2', ('i4', (2, 2)))])
+ dtype=[('x0', 'i4'), ('x1', ('i4', 2)),
+ ('x2', ('i4', (2, 2)))])
dd = structured_to_unstructured(d)
ddd = unstructured_to_structured(dd, d.dtype)
assert_(dd.base is d)
assert_equal(res, np.zeros((10, 6), dtype=int))
+ # test nested combinations of subarrays and structured arrays, gh-13333
+ def subarray(dt, shape):
+ return np.dtype((dt, shape))
+
+ def structured(*dts):
+ return np.dtype([('x{}'.format(i), dt) for i, dt in enumerate(dts)])
+
+ def inspect(dt, dtype=None):
+ arr = np.zeros((), dt)
+ ret = structured_to_unstructured(arr, dtype=dtype)
+ backarr = unstructured_to_structured(ret, dt)
+ return ret.shape, ret.dtype, backarr.dtype
+
+ dt = structured(subarray(structured(np.int32, np.int32), 3))
+ assert_equal(inspect(dt), ((6,), np.int32, dt))
+
+ dt = structured(subarray(subarray(np.int32, 2), 2))
+ assert_equal(inspect(dt), ((4,), np.int32, dt))
+
+ dt = structured(np.int32)
+ assert_equal(inspect(dt), ((1,), np.int32, dt))
+
+ dt = structured(np.int32, subarray(subarray(np.int32, 2), 2))
+ assert_equal(inspect(dt), ((5,), np.int32, dt))
+
+ dt = structured()
+ assert_raises(ValueError, structured_to_unstructured, np.zeros(3, dt))
+
+ # these currently don't work, but we may make it work in the future
+ assert_raises(NotImplementedError, structured_to_unstructured,
+ np.zeros(3, dt), dtype=np.int32)
+ assert_raises(NotImplementedError, unstructured_to_structured,
+ np.zeros((3,0), dtype=np.int32))
+
def test_field_assignment_by_name(self):
a = np.ones(2, dtype=[('a', 'i4'), ('b', 'f8'), ('c', 'u1')])
newdt = [('b', 'f4'), ('c', 'u1')]
compute_uv : bool, optional
Whether or not to compute `u` and `vh` in addition to `s`. True
by default.
+ hermitian : bool, optional
+ If True, `a` is assumed to be Hermitian (symmetric if real-valued),
+ enabling a more efficient method for finding singular values.
+ Defaults to False.
+
+ .. versionadded:: 1.17.0
Returns
-------
size as those of the input `a`. The size of the last two dimensions
depends on the value of `full_matrices`. Only returned when
`compute_uv` is True.
- hermitian : bool, optional
- If True, `a` is assumed to be Hermitian (symmetric if real-valued),
- enabling a more efficient method for finding singular values.
- Defaults to False.
-
- .. versionadded:: 1.17.0
Raises
------
return out[()]
# Array methods
- clip = _arraymethod('clip', onmask=False)
copy = _arraymethod('copy')
diagonal = _arraymethod('diagonal')
flatten = _arraymethod('flatten')
_localdict = ndarray.__getattribute__(self, '__dict__')
_data = ndarray.view(self, _localdict['_baseclass'])
obj = _data.getfield(*res)
- if obj.dtype.fields:
+ if obj.dtype.names is not None:
raise NotImplementedError("MaskedRecords is currently limited to"
"simple records.")
# Get some special attributes
assert_equal(clipped._data, x.clip(2, 8))
assert_equal(clipped._data, mx._data.clip(2, 8))
+ def test_clip_out(self):
+ # gh-14140
+ a = np.arange(10)
+ m = np.ma.MaskedArray(a, mask=[0, 1] * 5)
+ m.clip(0, 5, out=m)
+ assert_equal(m.mask, [0, 1] * 5)
+
def test_compress(self):
# test compress
a = masked_array([1., 2., 3., 4., 5.], fill_value=9999)
'zipf',
]
-from . import mtrand
+# add these for module-freeze analysis (like PyInstaller)
+from . import _pickle
+from . import common
+from . import bounded_integers
+from . import entropy
+
from .mtrand import *
from .generator import Generator, default_rng
from .bit_generator import SeedSequence
}
-def __generator_ctor(bit_generator_name='mt19937'):
+def __generator_ctor(bit_generator_name='MT19937'):
"""
Pickling helper function that returns a Generator object
return Generator(bit_generator())
-def __bit_generator_ctor(bit_generator_name='mt19937'):
+def __bit_generator_ctor(bit_generator_name='MT19937'):
"""
Pickling helper function that returns a bit generator object
return bit_generator()
-def __randomstate_ctor(bit_generator_name='mt19937'):
+def __randomstate_ctor(bit_generator_name='MT19937'):
"""
Pickling helper function that returns a legacy RandomState-like object
-from .common cimport bitgen_t
+from .common cimport bitgen_t, uint32_t
cimport numpy as np
cdef class BitGenerator():
cdef class SeedSequence():
cdef readonly object entropy
cdef readonly tuple spawn_key
- cdef readonly int pool_size
+ cdef readonly uint32_t pool_size
cdef readonly object pool
- cdef readonly int n_children_spawned
+ cdef readonly uint32_t n_children_spawned
cdef mix_entropy(self, np.ndarray[np.npy_uint32, ndim=1] mixer,
np.ndarray[np.npy_uint32, ndim=1] entropy_array)
Examples
--------
>>> import numpy as np
- >>> from np.random.bit_generator import _coerce_to_uint32_array
+ >>> from numpy.random.bit_generator import _coerce_to_uint32_array
>>> _coerce_to_uint32_array(12345)
array([12345], dtype=uint32)
>>> _coerce_to_uint32_array('12345')
-------
seqs : list of `SeedSequence` s
"""
+ cdef uint32_t i
+
seqs = []
for i in range(self.n_children_spawned,
self.n_children_spawned + n_children):
raise ValueError('Supplied output array is not contiguous, writable or aligned.')
if out_array.dtype != dtype:
raise TypeError('Supplied output array has the wrong type. '
- 'Expected {0}, got {0}'.format(dtype, out_array.dtype))
+ 'Expected {0}, got {1}'.format(np.dtype(dtype), out_array.dtype))
if size is not None:
try:
tup_size = tuple(size)
permutation(x)
Randomly permute a sequence, or return a permuted range.
-
If `x` is a multi-dimensional array, it is only shuffled along its
- first index.
+ first index.
Parameters
----------
[0, 1, 2],
[3, 4, 5]])
+ >>> rng.permutation("abc")
+ Traceback (most recent call last):
+ ...
+ numpy.AxisError: x must be an integer or at least 1-dimensional
"""
+
if isinstance(x, (int, np.integer)):
arr = np.arange(x)
self.shuffle(arr)
return arr
arr = np.asarray(x)
+ if arr.ndim < 1:
+ raise np.AxisError("x must be an integer or at least 1-dimensional")
# shuffle has fast-path for 1-d
if arr.ndim == 1:
out : ndarray
Permuted sequence or array range.
+
Examples
--------
>>> np.random.permutation(10)
[3, 4, 5]])
"""
+
if isinstance(x, (int, np.integer)):
arr = np.arange(x)
self.shuffle(arr)
return arr
arr = np.asarray(x)
+ if arr.ndim < 1:
+ raise IndexError("x must be an integer or at least 1-dimensional")
# shuffle has fast-path for 1-d
if arr.ndim == 1:
elif not is_msvc:
# Some bit generators require c99
EXTRA_COMPILE_ARGS += ['-std=c99']
- INTEL_LIKE = any([val in k.lower() for k in platform.uname()
- for val in ('x86', 'i686', 'i386', 'amd64')])
+ INTEL_LIKE = any(arch in platform.machine()
+ for arch in ('x86', 'i686', 'i386', 'amd64'))
if INTEL_LIKE:
# Assumes GCC or GCC-like compiler
EXTRA_COMPILE_ARGS += ['-msse2']
arr_2d = np.atleast_2d([1, 2, 3, 4, 5, 6, 7, 8, 9, 0]).T
actual = random.permutation(arr_2d)
assert_array_equal(actual, np.atleast_2d(desired).T)
+
+ bad_x_str = "abcd"
+ assert_raises(np.AxisError, random.permutation, bad_x_str)
+
+ bad_x_float = 1.2
+ assert_raises(np.AxisError, random.permutation, bad_x_float)
+
+ random = Generator(MT19937(self.seed))
+ integer_val = 10
+ desired = [3, 0, 8, 7, 9, 4, 2, 5, 1, 6]
+
+ actual = random.permutation(integer_val)
+ assert_array_equal(actual, desired)
def test_beta(self):
random = Generator(MT19937(self.seed))
actual = random.permutation(arr_2d)
assert_array_equal(actual, np.atleast_2d(desired).T)
+ random.seed(self.seed)
+ bad_x_str = "abcd"
+ assert_raises(IndexError, random.permutation, bad_x_str)
+
+ random.seed(self.seed)
+ bad_x_float = 1.2
+ assert_raises(IndexError, random.permutation, bad_x_float)
+
+ integer_val = 10
+ desired = [9, 0, 8, 5, 1, 3, 4, 7, 6, 2]
+
+ random.seed(self.seed)
+ actual = random.permutation(integer_val)
+ assert_array_equal(actual, desired)
+
def test_beta(self):
random.seed(self.seed)
actual = random.beta(.1, .9, size=(3, 2))
#-----------------------------------
# Path to the release notes
-RELEASE_NOTES = 'doc/release/1.17.0-notes.rst'
+RELEASE_NOTES = 'doc/release/1.17.1-notes.rst'
#-------------------------------------------------------
MAJOR = 1
MINOR = 17
-MICRO = 0
+MICRO = 1
ISRELEASED = True
VERSION = '%d.%d.%d' % (MAJOR, MINOR, MICRO)
pip install --upgrade pip setuptools
-pip install nose pytz cython pytest
+pip install pytz cython pytest==5.0.1
if [ -n "$USE_ASV" ]; then pip install asv; fi
popd