diff options
28 files changed, 335 insertions, 215 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ead627fb7..e70585d0c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -16,12 +16,12 @@ Thanks for your interest in contributing code to numpy! + If this is your first time contributing to a project on GitHub, please read through our -[guide to contributing to numpy](http://docs.scipy.org/doc/numpy-dev/dev/index.html) +[guide to contributing to numpy](http://docs.scipy.org/doc/numpy/dev/index.html) + If you have contributed to other projects on GitHub you can go straight to our -[development workflow](http://docs.scipy.org/doc/numpy-dev/dev/gitwash/development_workflow.html) +[development workflow](http://docs.scipy.org/doc/numpy/dev/gitwash/development_workflow.html) Either way, please be sure to follow our -[convention for commit messages](http://docs.scipy.org/doc/numpy-dev/dev/gitwash/development_workflow.html#writing-the-commit-message). +[convention for commit messages](http://docs.scipy.org/doc/numpy/dev/gitwash/development_workflow.html#writing-the-commit-message). If you are writing new C code, please follow the style described in ``doc/C_STYLE_GUIDE``. diff --git a/INSTALL.rst.txt b/INSTALL.rst.txt index 6f96daabf..d8ca80d92 100644 --- a/INSTALL.rst.txt +++ b/INSTALL.rst.txt @@ -41,7 +41,7 @@ nose__ http://nose.readthedocs.io If you want to build NumPy in order to work on NumPy itself, use ``runtests.py``. For more details, see - http://docs.scipy.org/doc/numpy-dev/dev/development_environment.html + http://docs.scipy.org/doc/numpy/dev/development_environment.html .. note:: diff --git a/doc/neps/nep-0000.rst b/doc/neps/nep-0000.rst index a7d6d7115..2eed19161 100644 --- a/doc/neps/nep-0000.rst +++ b/doc/neps/nep-0000.rst @@ -206,7 +206,7 @@ References and Footnotes .. _issue tracker: https://github.com/numpy/numpy/issues .. _NumPy Steering Council: - https://docs.scipy.org/doc/numpy-dev/dev/governance/governance.html + https://docs.scipy.org/doc/numpy/dev/governance/governance.html .. _`GitHub pull request`: https://github.com/numpy/numpy/pulls diff --git a/doc/release/1.15.0-notes.rst b/doc/release/1.15.0-notes.rst index 1bd0673b5..d076074ce 100644 --- a/doc/release/1.15.0-notes.rst +++ b/doc/release/1.15.0-notes.rst @@ -150,10 +150,10 @@ Improvements ``np.flip`` can operate over multiple axes ------------------------------------------ -``np.flip`` now accepts accepts None, or tuples of int, in its ``axis`` argument. If +``np.flip`` now accepts None, or tuples of int, in its ``axis`` argument. If axis is None, it will flip over all the axes. -``histogram`` and ``histogramdd` functions have moved to ``np.lib.histograms`` +``histogram`` and ``histogramdd`` functions have moved to ``np.lib.histograms`` ------------------------------------------------------------------------------ These were originally found in ``np.lib.function_base``. They are still available under their un-scoped ``np.histogram(dd)`` names, and @@ -165,7 +165,7 @@ with the new location, and should consider not using ``import *`` in future. ``histogram`` will accept NaN values when explicit bins are given ----------------------------------------------------------------- Previously it would fail when trying to compute a finite range for the data. -Since the range is ignored anyway when the bins are given explcitly, this error +Since the range is ignored anyway when the bins are given explicitly, this error was needless. Note that calling `histogram` on NaN values continues to raise the @@ -180,7 +180,7 @@ passed explicitly, and are not yet computed automatically. ``histogram`` "auto" estimator handles limited variance better ------------------------------------------------------------------------ No longer does an IQR of 0 result in `n_bins=1`, rather the number of bins -chosen is related to the data size in this situation +chosen is related to the data size in this situation. ``histogramdd`` allows explicit ranges to be given in a subset of axes ---------------------------------------------------------------------- @@ -188,7 +188,7 @@ The ``range`` argument of `histogramdd` can now contain ``None`` values to indicate that the range for the corresponding axis should be computed from the data. Previously, this could not be specified on a per-axis basis. -``np.r_`` works with 0d arrays, and ``np.ma.mr_` works with ``np.ma.masked`` +``np.r_`` works with 0d arrays, and ``np.ma.mr_`` works with ``np.ma.masked`` ---------------------------------------------------------------------------- 0d arrays passed to the `r_` and `mr_` concatenation helpers are now treated as though they are arrays of length 1. Previously, passing these was an error. @@ -252,7 +252,7 @@ operators to return expressions, to be compared elementwise with ``sort`` functions accept ``kind='stable'`` ------------------------------------------- -Up until now, to perform a stable sort on the data, the user must do:: +Up until now, to perform a stable sort on the data, the user must do: >>> np.sort([5, 2, 6, 2, 1], kind='mergesort') [1, 2, 2, 5, 6] diff --git a/doc/source/_templates/searchbox.html b/doc/source/_templates/searchbox.html new file mode 100644 index 000000000..d5ac2db5e --- /dev/null +++ b/doc/source/_templates/searchbox.html @@ -0,0 +1,23 @@ +{# + basic/searchbox.html + ~~~~~~~~~~~~~~~~~~~~ + + Sphinx sidebar template: quick search box. + + :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +#} +{%- if pagename != "search" and builder != "singlehtml" %} +<div id="searchbox" style="display: none" role="search"> + <h4>{{ _('Quick search') }}</h4> + <div> + <form class="search" action="{{ pathto('search') }}" method="get"> + <input type="text" style="width: inherit;" name="q" /> + <input type="submit" value="{{ _('search') }}" /> + <input type="hidden" name="check_keywords" value="yes" /> + <input type="hidden" name="area" value="default" /> + </form> + </div> +</div> +<script type="text/javascript">$('#searchbox').show(0);</script> +{%- endif %} diff --git a/doc/source/about.rst b/doc/source/about.rst index be1ced13e..24dc3d0a0 100644 --- a/doc/source/about.rst +++ b/doc/source/about.rst @@ -42,10 +42,6 @@ Our main means of communication are: More information about the development of NumPy can be found at our `Developer Zone <https://scipy.scipy.org/scipylib/dev-zone.html>`__. -If you want to fix issues in this documentation, the easiest way -is to participate in `our ongoing documentation marathon -<http://scipy.org/Developer_Zone/DocMarathon2008>`__. - About this documentation ======================== diff --git a/doc/source/conf.py b/doc/source/conf.py index 9e1d1a142..1472f5155 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -115,7 +115,7 @@ else: "scipy_org_logo": False, "rootlinks": [] } - html_sidebars = {'index': 'indexsidebar.html'} + html_sidebars = {'index': ['indexsidebar.html', 'searchbox.html']} html_additional_pages = { 'index': 'indexcontent.html', @@ -215,7 +215,7 @@ texinfo_documents = [ intersphinx_mapping = { 'python': ('https://docs.python.org/dev', None), 'scipy': ('https://docs.scipy.org/doc/scipy/reference', None), - 'matplotlib': ('http://matplotlib.org', None) + 'matplotlib': ('https://matplotlib.org', None) } diff --git a/doc/source/reference/index.rst b/doc/source/reference/index.rst index a2a8a0966..2140c57f7 100644 --- a/doc/source/reference/index.rst +++ b/doc/source/reference/index.rst @@ -35,10 +35,4 @@ Large parts of this manual originate from Travis E. Oliphant's book `Guide to NumPy <https://archive.org/details/NumPyBook>`__ (which generously entered Public Domain in August 2008). The reference documentation for many of the functions are written by numerous contributors and developers of -NumPy, both prior to and during the -`NumPy Documentation Marathon -<http://scipy.org/Developer_Zone/DocMarathon2008>`__. - -Please help to improve NumPy's documentation! Instructions on how to -join the ongoing documentation marathon can be found -`on the scipy.org website <http://scipy.org/Developer_Zone/DocMarathon2008>`__ +NumPy.
\ No newline at end of file diff --git a/doc/source/user/quickstart.rst b/doc/source/user/quickstart.rst index 7e1c381d2..de4079080 100644 --- a/doc/source/user/quickstart.rst +++ b/doc/source/user/quickstart.rst @@ -800,7 +800,7 @@ Copies and Views When operating and manipulating arrays, their data is sometimes copied into a new array and sometimes not. This is often a source of confusion -for beginners. There are three cases:: +for beginners. There are three cases: No Copy at All -------------- diff --git a/numpy/add_newdocs.py b/numpy/add_newdocs.py index c2d2c0949..8e8339355 100644 --- a/numpy/add_newdocs.py +++ b/numpy/add_newdocs.py @@ -6186,10 +6186,10 @@ add_newdoc('numpy.core', 'ufunc', ('at', 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 + ``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. + ``add.at(a, [0,0], 1)`` will increment the first element twice. .. versionadded:: 1.8.0 @@ -6214,8 +6214,6 @@ add_newdoc('numpy.core', 'ufunc', ('at', >>> print(a) array([-1, -2, 3, 4]) - :: - Increment items 0 and 1, and increment item 2 twice: >>> a = np.array([1, 2, 3, 4]) @@ -6223,8 +6221,6 @@ add_newdoc('numpy.core', 'ufunc', ('at', >>> print(a) array([2, 3, 5, 4]) - :: - Add items 0 and 1 in first array to second array, and store results in first array: @@ -7011,7 +7007,7 @@ add_newdoc('numpy.core.multiarray', 'datetime_as_string', arr : array_like of datetime64 The array of UTC timestamps to format. unit : str - One of None, 'auto', or a datetime unit. + 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 @@ -7039,13 +7035,13 @@ add_newdoc('numpy.core.multiarray', 'datetime_as_string', '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:: + ``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:: + 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'], @@ -7054,7 +7050,7 @@ add_newdoc('numpy.core.multiarray', 'datetime_as_string', array(['2002-10-27T04:30:00', '2002-10-27T05:30:00', '2002-10-27T06:30:00', '2002-10-27T07:30:00'], dtype='<U38') - But can be made to not lose precision:: + '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 diff --git a/numpy/core/arrayprint.py b/numpy/core/arrayprint.py index 7dc73d6de..adbbab6ed 100644 --- a/numpy/core/arrayprint.py +++ b/numpy/core/arrayprint.py @@ -132,44 +132,45 @@ def set_printoptions(precision=None, threshold=None, edgeitems=None, 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' + 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: - - '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. + + * '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 @@ -536,27 +537,27 @@ def array2string(a, max_line_width=None, precision=None, 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 - - 'void' : type `numpy.void` - - 'numpystr' : types `numpy.string_` and `numpy.unicode_` - - 'str' : all other strings - - Other keys that can be used to set a group of types at once are:: - - - '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' + 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 + - 'void' : type `numpy.void` + - 'numpystr' : types `numpy.string_` and `numpy.unicode_` + - 'str' : all other strings + + Other keys that can be used to set a group of types at once are: + + - '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' threshold : int, optional Total number of array elements which trigger summarization rather than full repr. @@ -571,20 +572,21 @@ def array2string(a, max_line_width=None, precision=None, floatmode : str, optional Controls the interpretation of the `precision` option for floating-point types. Can take the following values: - - '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. + + - '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 @@ -984,11 +986,12 @@ def format_float_scientific(x, precision=None, unique=True, trim='k', value. 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 + + * '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 @@ -1056,11 +1059,12 @@ def format_float_positional(x, precision=None, unique=True, digits, before or after the decimal point, ignoring leading zeros. trim : one of 'k', '.', '0', '-', optional Controls post-processing trimming of trailing digits, as follows: - 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 + + * '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 diff --git a/numpy/core/code_generators/ufunc_docstrings.py b/numpy/core/code_generators/ufunc_docstrings.py index 615970816..bd90d0460 100644 --- a/numpy/core/code_generators/ufunc_docstrings.py +++ b/numpy/core/code_generators/ufunc_docstrings.py @@ -3744,7 +3744,7 @@ add_newdoc('numpy.core.umath', 'ldexp', add_newdoc('numpy.core.umath', 'gcd', """ - Returns the greatest common divisor of |x1| and |x2| + Returns the greatest common divisor of ``|x1|`` and ``|x2|`` Parameters ---------- @@ -3774,7 +3774,7 @@ add_newdoc('numpy.core.umath', 'gcd', add_newdoc('numpy.core.umath', 'lcm', """ - Returns the lowest common multiple of |x1| and |x2| + Returns the lowest common multiple of ``|x1|`` and ``|x2|`` Parameters ---------- diff --git a/numpy/core/src/multiarray/descriptor.c b/numpy/core/src/multiarray/descriptor.c index 8d983ffc9..c1c1ce568 100644 --- a/numpy/core/src/multiarray/descriptor.c +++ b/numpy/core/src/multiarray/descriptor.c @@ -243,7 +243,7 @@ is_datetime_typestr(char *type, Py_ssize_t len) } static PyArray_Descr * -_convert_from_tuple(PyObject *obj) +_convert_from_tuple(PyObject *obj, int align) { PyArray_Descr *type, *res; PyObject *val; @@ -252,9 +252,16 @@ _convert_from_tuple(PyObject *obj) if (PyTuple_GET_SIZE(obj) != 2) { return NULL; } - if (!PyArray_DescrConverter(PyTuple_GET_ITEM(obj,0), &type)) { - return NULL; + if (align) { + if (!PyArray_DescrAlignConverter(PyTuple_GET_ITEM(obj, 0), &type)) { + return NULL; + } } + else { + if (!PyArray_DescrConverter(PyTuple_GET_ITEM(obj, 0), &type)) { + return NULL; + } + } val = PyTuple_GET_ITEM(obj,1); /* try to interpret next item as a type */ res = _use_inherit(type, val, &errflag); @@ -1547,7 +1554,7 @@ PyArray_DescrConverter(PyObject *obj, PyArray_Descr **at) } else if (PyTuple_Check(obj)) { /* or a tuple */ - *at = _convert_from_tuple(obj); + *at = _convert_from_tuple(obj, 0); if (*at == NULL){ if (PyErr_Occurred()) { return NPY_FAIL; @@ -2928,6 +2935,9 @@ PyArray_DescrAlignConverter(PyObject *obj, PyArray_Descr **at) *at = _convert_from_commastring(tmp, 1); Py_DECREF(tmp); } + else if (PyTuple_Check(obj)) { + *at = _convert_from_tuple(obj, 1); + } else if (PyList_Check(obj)) { *at = _convert_from_array_descr(obj, 1); } diff --git a/numpy/core/src/multiarray/multiarraymodule.c b/numpy/core/src/multiarray/multiarraymodule.c index 0008cb04b..7eccb4a4b 100644 --- a/numpy/core/src/multiarray/multiarraymodule.c +++ b/numpy/core/src/multiarray/multiarraymodule.c @@ -4732,10 +4732,10 @@ static struct PyModuleDef moduledef = { /* Initialization function for the module */ #if defined(NPY_PY3K) -#define RETVAL m +#define RETVAL(x) x PyMODINIT_FUNC PyInit_multiarray(void) { #else -#define RETVAL +#define RETVAL(x) PyMODINIT_FUNC initmultiarray(void) { #endif PyObject *m, *d, *s; @@ -4763,6 +4763,10 @@ PyMODINIT_FUNC initmultiarray(void) { /* Initialize access to the PyDateTime API */ numpy_pydatetime_import(); + if (PyErr_Occurred()) { + goto err; + } + /* Add some symbolic constants to the module */ d = PyModule_GetDict(m); if (!d) { @@ -4776,7 +4780,7 @@ PyMODINIT_FUNC initmultiarray(void) { */ PyArray_Type.tp_hash = PyObject_HashNotImplemented; if (PyType_Ready(&PyArray_Type) < 0) { - return RETVAL; + goto err; } if (setup_scalartypes(d) < 0) { goto err; @@ -4786,32 +4790,32 @@ PyMODINIT_FUNC initmultiarray(void) { PyArrayMultiIter_Type.tp_iter = PyObject_SelfIter; PyArrayMultiIter_Type.tp_free = PyArray_free; if (PyType_Ready(&PyArrayIter_Type) < 0) { - return RETVAL; + goto err; } if (PyType_Ready(&PyArrayMapIter_Type) < 0) { - return RETVAL; + goto err; } if (PyType_Ready(&PyArrayMultiIter_Type) < 0) { - return RETVAL; + goto err; } PyArrayNeighborhoodIter_Type.tp_new = PyType_GenericNew; if (PyType_Ready(&PyArrayNeighborhoodIter_Type) < 0) { - return RETVAL; + goto err; } if (PyType_Ready(&NpyIter_Type) < 0) { - return RETVAL; + goto err; } PyArrayDescr_Type.tp_hash = PyArray_DescrHash; if (PyType_Ready(&PyArrayDescr_Type) < 0) { - return RETVAL; + goto err; } if (PyType_Ready(&PyArrayFlags_Type) < 0) { - return RETVAL; + goto err; } NpyBusDayCalendar_Type.tp_new = PyType_GenericNew; if (PyType_Ready(&NpyBusDayCalendar_Type) < 0) { - return RETVAL; + goto err; } c_api = NpyCapsule_FromVoidPtr((void *)PyArray_API, NULL); @@ -4897,12 +4901,13 @@ PyMODINIT_FUNC initmultiarray(void) { if (set_typeinfo(d) != 0) { goto err; } - return RETVAL; + + return RETVAL(m); err: if (!PyErr_Occurred()) { PyErr_SetString(PyExc_RuntimeError, "cannot load multiarray module."); } - return RETVAL; + return RETVAL(NULL); } diff --git a/numpy/core/src/multiarray/scalartypes.c.src b/numpy/core/src/multiarray/scalartypes.c.src index 9df635dee..cb4af0d12 100644 --- a/numpy/core/src/multiarray/scalartypes.c.src +++ b/numpy/core/src/multiarray/scalartypes.c.src @@ -1607,7 +1607,8 @@ static PyGetSetDef gentype_getsets[] = { /* 0-dim array from scalar object */ -static char doc_getarray[] = "sc.__array__(|type) return 0-dim array"; +static char doc_getarray[] = "sc.__array__(dtype) return 0-dim array from " + "scalar with specified dtype"; static PyObject * gentype_getarray(PyObject *scalar, PyObject *args) diff --git a/numpy/core/src/umath/umathmodule.c b/numpy/core/src/umath/umathmodule.c index 03bf5bfd8..15da831b2 100644 --- a/numpy/core/src/umath/umathmodule.c +++ b/numpy/core/src/umath/umathmodule.c @@ -310,10 +310,10 @@ static struct PyModuleDef moduledef = { #include <stdio.h> #if defined(NPY_PY3K) -#define RETVAL m +#define RETVAL(x) x PyMODINIT_FUNC PyInit_umath(void) #else -#define RETVAL +#define RETVAL(x) PyMODINIT_FUNC initumath(void) #endif { @@ -330,7 +330,7 @@ PyMODINIT_FUNC initumath(void) m = Py_InitModule("umath", methods); #endif if (!m) { - return RETVAL; + goto err; } /* Import the array */ @@ -339,12 +339,12 @@ PyMODINIT_FUNC initumath(void) PyErr_SetString(PyExc_ImportError, "umath failed: Could not import array core."); } - return RETVAL; + goto err; } /* Initialize the types */ if (PyType_Ready(&PyUFunc_Type) < 0) - return RETVAL; + goto err; /* Add some symbolic constants to the module */ d = PyModule_GetDict(m); @@ -426,7 +426,7 @@ PyMODINIT_FUNC initumath(void) goto err; } - return RETVAL; + return RETVAL(m); err: /* Check for errors */ @@ -434,5 +434,5 @@ PyMODINIT_FUNC initumath(void) PyErr_SetString(PyExc_RuntimeError, "cannot load umath module."); } - return RETVAL; + return RETVAL(NULL); } diff --git a/numpy/core/tests/test_dtype.py b/numpy/core/tests/test_dtype.py index 35b8f6868..27fbb10d5 100644 --- a/numpy/core/tests/test_dtype.py +++ b/numpy/core/tests/test_dtype.py @@ -205,6 +205,14 @@ class TestRecord(object): assert_equal(dt3.itemsize, 11) assert_equal(dt1, dt2) assert_equal(dt2, dt3) + # Array of subtype should preserve alignment + dt1 = np.dtype([('a', '|i1'), + ('b', [('f0', '<i2'), + ('f1', '<f4')], 2)], align=True) + assert_equal(dt1.descr, [('a', '|i1'), ('', '|V3'), + ('b', [('f0', '<i2'), ('', '|V2'), + ('f1', '<f4')], (2,))]) + def test_union_struct(self): # Should be able to create union dtypes diff --git a/numpy/doc/constants.py b/numpy/doc/constants.py index f3b835085..21c7a3c67 100644 --- a/numpy/doc/constants.py +++ b/numpy/doc/constants.py @@ -296,8 +296,9 @@ add_newdoc('numpy', 'nan', See Also -------- isnan : Shows which elements are Not a Number. + isfinite : Shows which elements are finite (not one of - Not a Number, positive infinity and negative infinity) + Not a Number, positive infinity and negative infinity) Notes ----- diff --git a/numpy/doc/misc.py b/numpy/doc/misc.py index 5d6708a0d..24369871c 100644 --- a/numpy/doc/misc.py +++ b/numpy/doc/misc.py @@ -209,7 +209,7 @@ Only a survey of the choices. Little detail on how each works. Interfacing to Fortran: ----------------------- The clear choice to wrap Fortran code is -`f2py <http://docs.scipy.org/doc/numpy-dev/f2py/>`_. +`f2py <http://docs.scipy.org/doc/numpy/f2py/>`_. Pyfort is an older alternative, but not supported any longer. Fwrap is a newer project that looked promising but isn't being developed any diff --git a/numpy/fft/fftpack_litemodule.c b/numpy/fft/fftpack_litemodule.c index dfa0d211b..bd6cfc120 100644 --- a/numpy/fft/fftpack_litemodule.c +++ b/numpy/fft/fftpack_litemodule.c @@ -330,10 +330,10 @@ static struct PyModuleDef moduledef = { /* Initialization function for the module */ #if PY_MAJOR_VERSION >= 3 -#define RETVAL m +#define RETVAL(x) x PyMODINIT_FUNC PyInit_fftpack_lite(void) #else -#define RETVAL +#define RETVAL(x) PyMODINIT_FUNC initfftpack_lite(void) #endif @@ -348,6 +348,9 @@ initfftpack_lite(void) fftpack_module_documentation, (PyObject*)NULL,PYTHON_API_VERSION); #endif + if (m == NULL) { + return RETVAL(NULL); + } /* Import the array object */ import_array(); @@ -359,5 +362,5 @@ initfftpack_lite(void) /* XXXX Add constants here */ - return RETVAL; + return RETVAL(m); } diff --git a/numpy/lib/_version.py b/numpy/lib/_version.py index 0019c5607..c3563a7fa 100644 --- a/numpy/lib/_version.py +++ b/numpy/lib/_version.py @@ -45,7 +45,7 @@ class NumpyVersion(): Examples -------- >>> from numpy.lib import NumpyVersion - >>> if NumpyVersion(np.__version__) < '1.7.0'): + >>> if NumpyVersion(np.__version__) < '1.7.0': ... print('skip') skip diff --git a/numpy/lib/function_base.py b/numpy/lib/function_base.py index a4516c276..099b63c40 100644 --- a/numpy/lib/function_base.py +++ b/numpy/lib/function_base.py @@ -3424,17 +3424,19 @@ def percentile(a, q, axis=None, out=None, If True, then allow the input array `a` to be modified by intermediate calculations, to save memory. In this case, the contents of the input `a` after this function completes is undefined. + interpolation : {'linear', 'lower', 'higher', 'midpoint', 'nearest'} This optional parameter specifies the interpolation method to use when the desired quantile lies between two data points ``i < j``: - * linear: ``i + (j - i) * fraction``, where ``fraction`` - is the fractional part of the index surrounded by ``i`` - and ``j``. - * lower: ``i``. - * higher: ``j``. - * nearest: ``i`` or ``j``, whichever is nearest. - * midpoint: ``(i + j) / 2``. + + * 'linear': ``i + (j - i) * fraction``, where ``fraction`` + is the fractional part of the index surrounded by ``i`` + and ``j``. + * 'lower': ``i``. + * 'higher': ``j``. + * 'nearest': ``i`` or ``j``, whichever is nearest. + * 'midpoint': ``(i + j) / 2``. .. versionadded:: 1.9.0 keepdims : bool, optional @@ -3503,18 +3505,19 @@ def percentile(a, q, axis=None, out=None, The different types of interpolation can be visualized graphically: - ..plot:: + .. plot:: + import matplotlib.pyplot as plt a = np.arange(4) p = np.linspace(0, 100, 6001) ax = plt.gca() lines = [ - ('linear', None) - ('higher', '--') - ('lower', '--') - ('nearest', '-.') - ('midpoint', '-.') + ('linear', None), + ('higher', '--'), + ('lower', '--'), + ('nearest', '-.'), + ('midpoint', '-.'), ] for interpolation, style in lines: ax.plot( diff --git a/numpy/lib/mixins.py b/numpy/lib/mixins.py index 3220f6534..0379ecb1a 100644 --- a/numpy/lib/mixins.py +++ b/numpy/lib/mixins.py @@ -74,8 +74,8 @@ class NDArrayOperatorsMixin(object): It is useful for writing classes that do not inherit from `numpy.ndarray`, but that should support arithmetic and numpy universal functions like - arrays as described in :ref:`A Mechanism for Overriding Ufuncs - <neps.ufunc-overrides>`. + arrays as described in `A Mechanism for Overriding Ufuncs + <../../neps/nep-0013-ufunc-overrides.html>`_. As an trivial example, consider this implementation of an ``ArrayLike`` class that simply wraps a NumPy array and ensures that the result of any diff --git a/numpy/lib/nanfunctions.py b/numpy/lib/nanfunctions.py index 16e363d7c..dddc0e5b8 100644 --- a/numpy/lib/nanfunctions.py +++ b/numpy/lib/nanfunctions.py @@ -1059,13 +1059,14 @@ def nanpercentile(a, q, axis=None, out=None, overwrite_input=False, This optional parameter specifies the interpolation method to use when the desired quantile lies between two data points ``i < j``: - * linear: ``i + (j - i) * fraction``, where ``fraction`` - is the fractional part of the index surrounded by ``i`` - and ``j``. - * lower: ``i``. - * higher: ``j``. - * nearest: ``i`` or ``j``, whichever is nearest. - * midpoint: ``(i + j) / 2``. + + * 'linear': ``i + (j - i) * fraction``, where ``fraction`` + is the fractional part of the index surrounded by ``i`` + and ``j``. + * 'lower': ``i``. + * 'higher': ``j``. + * 'nearest': ``i`` or ``j``, whichever is nearest. + * 'midpoint': ``(i + j) / 2``. 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 diff --git a/numpy/lib/npyio.py b/numpy/lib/npyio.py index 29688f73d..59379bdda 100644 --- a/numpy/lib/npyio.py +++ b/numpy/lib/npyio.py @@ -1166,13 +1166,14 @@ def savetxt(fname, X, fmt='%.18e', delimiter=' ', newline='\n', header='', multi-format string, e.g. 'Iteration %d -- %10.5f', in which case `delimiter` is ignored. For complex `X`, the legal options for `fmt` are: - a) a single specifier, `fmt='%.4e'`, resulting in numbers formatted - like `' (%s+%sj)' % (fmt, fmt)` - b) a full string specifying every real and imaginary part, e.g. - `' %.4e %+.4ej %.4e %+.4ej %.4e %+.4ej'` for 3 columns - c) a list of specifiers, one per column - in this case, the real - and imaginary part must have separate specifiers, - e.g. `['%.3e + %.3ej', '(%.15e%+.15ej)']` for 2 columns + + * a single specifier, `fmt='%.4e'`, resulting in numbers formatted + like `' (%s+%sj)' % (fmt, fmt)` + * a full string specifying every real and imaginary part, e.g. + `' %.4e %+.4ej %.4e %+.4ej %.4e %+.4ej'` for 3 columns + * a list of specifiers, one per column - in this case, the real + and imaginary part must have separate specifiers, + e.g. `['%.3e + %.3ej', '(%.15e%+.15ej)']` for 2 columns delimiter : str, optional String or character separating columns. newline : str, optional diff --git a/numpy/linalg/lapack_litemodule.c b/numpy/linalg/lapack_litemodule.c index bdde2e22d..696a6d874 100644 --- a/numpy/linalg/lapack_litemodule.c +++ b/numpy/linalg/lapack_litemodule.c @@ -331,10 +331,10 @@ static struct PyModuleDef moduledef = { /* Initialization function for the module */ #if PY_MAJOR_VERSION >= 3 -#define RETVAL m +#define RETVAL(x) x PyMODINIT_FUNC PyInit_lapack_lite(void) #else -#define RETVAL +#define RETVAL(x) PyMODINIT_FUNC initlapack_lite(void) #endif @@ -347,12 +347,12 @@ initlapack_lite(void) "", (PyObject*)NULL,PYTHON_API_VERSION); #endif if (m == NULL) { - return RETVAL; + return RETVAL(NULL); } import_array(); d = PyModule_GetDict(m); LapackError = PyErr_NewException("lapack_lite.LapackError", NULL, NULL); PyDict_SetItemString(d, "LapackError", LapackError); - return RETVAL; + return RETVAL(m); } diff --git a/numpy/linalg/linalg.py b/numpy/linalg/linalg.py index 4905690ad..5ee230f92 100644 --- a/numpy/linalg/linalg.py +++ b/numpy/linalg/linalg.py @@ -2036,17 +2036,9 @@ def lstsq(a, b, rcond="warn"): else: gufunc = _umath_linalg.lstsq_n - signature = 'DDd->Did' if isComplexType(t) else 'ddd->did' + signature = 'DDd->Ddid' if isComplexType(t) else 'ddd->ddid' extobj = get_linalg_error_extobj(_raise_linalgerror_lstsq) - b_out, rank, s = gufunc(a, b, rcond, signature=signature, extobj=extobj) - - # b_out contains both the solution and the components of the residuals - x = b_out[...,:n,:] - r_parts = b_out[...,n:,:] - if isComplexType(t): - resids = sum(abs(r_parts)**2, axis=-2) - else: - resids = sum(r_parts**2, axis=-2) + x, resids, rank, s = gufunc(a, b, rcond, signature=signature, extobj=extobj) # remove the axis we added if is_1d: diff --git a/numpy/linalg/umath_linalg.c.src b/numpy/linalg/umath_linalg.c.src index d8cfdf6ac..03fdd387a 100644 --- a/numpy/linalg/umath_linalg.c.src +++ b/numpy/linalg/umath_linalg.c.src @@ -765,6 +765,10 @@ fortran_int_max(fortran_int x, fortran_int y) { INIT_OUTER_LOOP_5\ npy_intp s5 = *steps++; +#define INIT_OUTER_LOOP_7 \ + INIT_OUTER_LOOP_6\ + npy_intp s6 = *steps++; + #define BEGIN_OUTER_LOOP_2 \ for (N_ = 0;\ N_ < dN;\ @@ -805,6 +809,17 @@ fortran_int_max(fortran_int x, fortran_int y) { args[4] += s4,\ args[5] += s5) { +#define BEGIN_OUTER_LOOP_7 \ + for (N_ = 0;\ + N_ < dN;\ + N_++, args[0] += s0,\ + args[1] += s1,\ + args[2] += s2,\ + args[3] += s3,\ + args[4] += s4,\ + args[5] += s5,\ + args[6] += s6) { + #define END_OUTER_LOOP } static NPY_INLINE void @@ -836,6 +851,7 @@ update_pointers(npy_uint8** bases, ptrdiff_t* offsets, size_t count) #typ = float, double, COMPLEX_t, DOUBLECOMPLEX_t# #copy = scopy, dcopy, ccopy, zcopy# #nan = s_nan, d_nan, c_nan, z_nan# + #zero = s_zero, d_zero, c_zero, z_zero# */ static NPY_INLINE void * linearize_@TYPE@_matrix(void *dst_in, @@ -949,6 +965,23 @@ nan_@TYPE@_matrix(void *dst_in, const LINEARIZE_DATA_t* data) } } +static NPY_INLINE void +zero_@TYPE@_matrix(void *dst_in, const LINEARIZE_DATA_t* data) +{ + @typ@ *dst = (@typ@ *) dst_in; + + int i, j; + for (i = 0; i < data->rows; i++) { + @typ@ *cp = dst; + ptrdiff_t cs = data->column_strides/sizeof(@typ@); + for (j = 0; j < data->columns; ++j) { + *cp = @zero@; + cp += cs; + } + dst += data->row_strides/sizeof(@typ@); + } +} + /**end repeat**/ /* identity square matrix generation */ @@ -3196,6 +3229,12 @@ init_@lapack_func@(GELSD_PARAMS_t *params, #TYPE=FLOAT,DOUBLE,CFLOAT,CDOUBLE# #REALTYPE=FLOAT,DOUBLE,FLOAT,DOUBLE# #lapack_func=sgelsd,dgelsd,cgelsd,zgelsd# + #dot_func=sdot,ddot,cdotc,zdotc# + #typ = npy_float, npy_double, npy_cfloat, npy_cdouble# + #basetyp = npy_float, npy_double, npy_float, npy_double# + #ftyp = fortran_real, fortran_doublereal, + fortran_complex, fortran_doublecomplex# + #cmplx = 0, 0, 1, 1# */ static inline void release_@lapack_func@(GELSD_PARAMS_t* params) @@ -3206,6 +3245,22 @@ release_@lapack_func@(GELSD_PARAMS_t* params) memset(params, 0, sizeof(*params)); } +/** Compute the squared l2 norm of a contiguous vector */ +static @basetyp@ +@TYPE@_abs2(@typ@ *p, npy_intp n) { + npy_intp i; + @basetyp@ res = 0; + for (i = 0; i < n; i++) { + @typ@ el = p[i]; +#if @cmplx@ + res += el.real*el.real + el.imag*el.imag; +#else + res += el*el; +#endif + } + return res; +} + static void @TYPE@_lstsq(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_UNUSED(func)) @@ -3213,21 +3268,25 @@ static void GELSD_PARAMS_t params; int error_occurred = get_fp_invalid_and_clear(); fortran_int n, m, nrhs; - INIT_OUTER_LOOP_6 + fortran_int excess; + + INIT_OUTER_LOOP_7 m = (fortran_int)dimensions[0]; n = (fortran_int)dimensions[1]; nrhs = (fortran_int)dimensions[2]; + excess = m - n; if (init_@lapack_func@(¶ms, m, n, nrhs)) { - LINEARIZE_DATA_t a_in, b_in, x_out, s_out; + LINEARIZE_DATA_t a_in, b_in, x_out, s_out, r_out; init_linearize_data(&a_in, n, m, steps[1], steps[0]); init_linearize_data_ex(&b_in, nrhs, m, steps[3], steps[2], fortran_int_max(n, m)); - init_linearize_data(&x_out, nrhs, fortran_int_max(n, m), steps[5], steps[4]); - init_linearize_data(&s_out, 1, fortran_int_min(n, m), 1, steps[6]); + init_linearize_data_ex(&x_out, nrhs, n, steps[5], steps[4], fortran_int_max(n, m)); + init_linearize_data(&r_out, 1, nrhs, 1, steps[6]); + init_linearize_data(&s_out, 1, fortran_int_min(n, m), 1, steps[7]); - BEGIN_OUTER_LOOP_6 + BEGIN_OUTER_LOOP_7 int not_ok; linearize_@TYPE@_matrix(params.A, args[0], &a_in); linearize_@TYPE@_matrix(params.B, args[1], &b_in); @@ -3235,13 +3294,35 @@ static void not_ok = call_@lapack_func@(¶ms); if (!not_ok) { delinearize_@TYPE@_matrix(args[3], params.B, &x_out); - *(npy_int*) args[4] = params.RANK; - delinearize_@REALTYPE@_matrix(args[5], params.S, &s_out); + *(npy_int*) args[5] = params.RANK; + delinearize_@REALTYPE@_matrix(args[6], params.S, &s_out); + + /* Note that linalg.lstsq discards this when excess == 0 */ + if (excess >= 0 && params.RANK == n) { + /* Compute the residuals as the square sum of each column */ + int i; + char *resid = args[4]; + @ftyp@ *components = (@ftyp@ *)params.B + n; + for (i = 0; i < nrhs; i++) { + @ftyp@ *vector = components + i*m; + /* Numpy and fortran floating types are the same size, + * so this case is safe */ + @basetyp@ abs2 = @TYPE@_abs2((@typ@ *)vector, excess); + memcpy( + resid + i*r_out.column_strides, + &abs2, sizeof(abs2)); + } + } + else { + /* Note that this is always discarded by linalg.lstsq */ + nan_@REALTYPE@_matrix(args[4], &r_out); + } } else { error_occurred = 1; nan_@TYPE@_matrix(args[3], &x_out); - *(npy_int*) args[4] = -1; - nan_@REALTYPE@_matrix(args[5], &s_out); + nan_@REALTYPE@_matrix(args[4], &r_out); + *(npy_int*) args[5] = -1; + nan_@REALTYPE@_matrix(args[6], &s_out); } END_OUTER_LOOP @@ -3389,12 +3470,12 @@ static char svd_1_3_types[] = { NPY_CDOUBLE, NPY_CDOUBLE, NPY_DOUBLE, NPY_CDOUBLE }; -/* A, b, rcond, x, rank, s */ +/* A, b, rcond, x, resid, rank, s, */ static char lstsq_types[] = { - NPY_FLOAT, NPY_FLOAT, NPY_FLOAT, NPY_FLOAT, NPY_INT, NPY_FLOAT, - NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_INT, NPY_DOUBLE, - NPY_CFLOAT, NPY_CFLOAT, NPY_FLOAT, NPY_CFLOAT, NPY_INT, NPY_FLOAT, - NPY_CDOUBLE, NPY_CDOUBLE, NPY_DOUBLE, NPY_CDOUBLE, NPY_INT, NPY_DOUBLE + NPY_FLOAT, NPY_FLOAT, NPY_FLOAT, NPY_FLOAT, NPY_FLOAT, NPY_INT, NPY_FLOAT, + NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_INT, NPY_DOUBLE, + NPY_CFLOAT, NPY_CFLOAT, NPY_FLOAT, NPY_CFLOAT, NPY_FLOAT, NPY_INT, NPY_FLOAT, + NPY_CDOUBLE, NPY_CDOUBLE, NPY_DOUBLE, NPY_CDOUBLE, NPY_DOUBLE, NPY_INT, NPY_DOUBLE, }; typedef struct gufunc_descriptor_struct { @@ -3590,19 +3671,19 @@ GUFUNC_DESCRIPTOR_t gufunc_descriptors [] = { }, { "lstsq_m", - "(m,n),(m,nrhs),()->(n,nrhs),(),(m)", + "(m,n),(m,nrhs),()->(n,nrhs),(nrhs),(),(m)", "least squares on the last two dimensions and broadcast to the rest. \n"\ "For m <= n. \n", - 4, 3, 3, + 4, 3, 4, FUNC_ARRAY_NAME(lstsq), lstsq_types }, { "lstsq_n", - "(m,n),(m,nrhs),()->(m,nrhs),(),(n)", + "(m,n),(m,nrhs),()->(n,nrhs),(nrhs),(),(n)", "least squares on the last two dimensions and broadcast to the rest. \n"\ - "For m >= n. \n", - 4, 3, 3, + "For m >= n, meaning that residuals are produced. \n", + 4, 3, 4, FUNC_ARRAY_NAME(lstsq), lstsq_types } @@ -3659,10 +3740,10 @@ static struct PyModuleDef moduledef = { #endif #if defined(NPY_PY3K) -#define RETVAL m +#define RETVAL(x) x PyObject *PyInit__umath_linalg(void) #else -#define RETVAL +#define RETVAL(x) PyMODINIT_FUNC init_umath_linalg(void) #endif @@ -3678,7 +3759,7 @@ init_umath_linalg(void) m = Py_InitModule(UMATH_LINALG_MODULE_NAME, UMath_LinAlgMethods); #endif if (m == NULL) { - return RETVAL; + return RETVAL(NULL); } import_array(); @@ -3696,7 +3777,8 @@ init_umath_linalg(void) if (PyErr_Occurred()) { PyErr_SetString(PyExc_RuntimeError, "cannot load _umath_linalg module."); + return RETVAL(NULL); } - return RETVAL; + return RETVAL(m); } |
